Promise basic principle & asynchronous

Time:2020-10-18
Author: Chen Jiabin
email: [email protected]
date: 2018/2/23

Promise basic implementation

var PENDING = 0;
var FULFILLED = 1;
var REJECTED = 2;

function Promise(fn) {
    var state = PENDING;
    var value = null;
    var handlers = [];

    doResolve(fn, resolve, reject)

    function fulfill(result) {}
    // state=fulfilled, value=result

    function reject(error) {}
    // state=rejected, value=error

    function resolve(result) {}
    //If then in result (result is promise), execute do resolve
    //Else execute fulfill
    
    function doResolve(fn, onFulfilled, onRejected) {}
    //Pass in the resolve and reject functions to FN
    //Resolve function, execute onfulfilled
    //The reject function executes onrejected
    
    function handle(handler) {}
    // if PENDING, push handler
    //If fully led, execute the onfulfilled function in the handler
    //If rejected, execute the onrejected function in handler
    
    this.done = function (onFulfilled, onRejected) {}
    //Asynchronous (setTimeout 0) execution handler ({onfulfilled, onrejected})
    
    this.then = function (onFulfilled, onRejected) {
        var self = this
        return new Promise((resolve,reject)=>{
            return self.done(result=>{
                if onFulfilled
                    return resolve(onFulfilled(result))
                else 
                    return resolve(result)
            }, err=>{
                if onRejected
                    return resolve(onRejected(err))
                else
                    return reject(err)
            })
        })
    }
}

Basic grammar

new Promsie((resolve, reject) => {
    // function1()
    resolve()
}).then(() => {
    // function2()
})

Here, function1 is executed synchronously and function2 is executed asynchronously

Promise current cycle & secondary cycle

I thought that the content of promise would stop here. Later, I saw a blog written by Ruan teacher, which said that there are two kinds of asynchronous, what?!!

Asynchronous tasks can be divided into two types.

  • Added inThis cycleAsynchronous tasks for
  • Added inSecondary cycleAsynchronous tasks for

Node provides that,process.nextTickandPromiseThe callback function is appended to the current cycle, that is, once the synchronization task is completed, it starts to execute them. andsetTimeoutsetIntervalsetImmediateThe callback function is appended in the secondary loop.

Two types of asynchrony have opened my eyes. But in my knowledge world, promise uses setTimeout to realize asynchronism. Why do promise and setTimeout belong to different asynchronous types?

OK, find promise’s Polyfill code right now

if (isNode) {
  scheduleFlush = useNextTick();
} else if (BrowserMutationObserver) { // BrowserMutationObserver = window.MutationObserver
  scheduleFlush = useMutationObserver();
} else if (isWorker) { // typeof Uint8ClampedArray !== 'undefined' && typeof importScripts !== 'undefined' && typeof MessageChannel !== 'undefined'
  scheduleFlush = useMessageChannel();
} else if (browserWindow === undefined && typeof require === 'function') { // browserWindow = typeof window !== 'undefined' ? window : undefined
  scheduleFlush = attemptVertx();
} else {
  scheduleFlush = useSetTimeout();
}

It turns out that promise’s asynchronism is not just setTimeout. Here, different implementations will be adopted according to different environments. The browser mainly uses mutationobserver and setTimeout

Let’s take a look at the compatibility of the mutationobserver https://developer.mozilla.org… )

Promise basic principle & asynchronous

Promise basic principle & asynchronous

As can be seen from the above figure, promise is implemented by mutationobserver from the above versionThis cycleThe asynchronous tasks of, which are lower than the above versions, are implemented by setTimeoutSecondary cycleThe asynchronous task of (the current loop is executed before the next). The specific differences are as follows:

// ie11
setTimeout(function () {console.log(1)});
Promise.resolve().then(function () {
  console.log(2);
});
//The output is 21

// ie10
setTimeout(function () {console.log(1)});
Promise.resolve().then(function () {
  console.log(2);
});
//The output is 1.2

other

shim VS polyfill

  • Shim, a library that brings new APIs to browsers, such as jQuery
  • Polyfill is a patch and supplement for browsers, which makes its behavior consistent with other browsers, such as promise Polyfill

The origin of the word Polyfill:

Polyfilla is a UK product known as Spackling Paste in the US. With that in mind: think of the browsers as a wall with cracks in it. These [polyfills] help smooth out the cracks and give us a nice smooth wall of browsers to work with.——Remy Sharp

reference material

  1. Detailed explanation of node timer, Ruan Yifeng, February 23, 2018, http://www.ruanyifeng.com/blo…
  2. What is the difference between a shim and a polyfill? ,stack overflow,closed at Jul 30 ’15,https://stackoverflow.com/que…
  3. 《Speaking JavaScript》,Axel Rauschmayer,March 2014,http://speakingjs.com/es5/ch3…