Why does my function execute before my promise callback?

笑着哭i 提交于 2021-02-05 11:27:07

问题


Why does a function called after my promise execute before the promise's callback?

I read this in MDN, but didn't understand it

"Callbacks will never be called before the completion of the current run of the JavaScript event loop."

I thought it meant that if I have any other statements after resolve() or reject() they will get executed before the callback is invoked. Though, that seems to be an incomplete understanding.

function myFunction() {
  return new Promise( function(resolve, reject) {

    const err = false;

    if(err) {
      reject("Something went wrong!!!");
    }
    else {
      resolve("All good");
    }
  });
}

myFunction().then(doSuccess).catch(doError);
doOther();

function doError(err) {
  console.log(err);
}

function doSuccess() {
  console.log('Success');
}

function doOther() {
  console.log("My Other Function");
}

Output:

My Other Function

Success


回答1:


By specification, a promise .then() or .catch() callback is never called synchronously, but is called on a future tick of the event loop. That means that the rest of your synchronous code always runs before any .then() handler is called.

So, thus your doOther() function runs before either doSuccess() or doError() are called.

Promises are designed this way so that a promise .then() handler will be called with consistent timing whether the promise is resolved immediately or resolved some time in the future. If synchronous .then() handlers were allowed, then calling code would either have to know when it might get called synchronously or you'd be susceptible to weird timing bugs.

In the Promises/A+ specification which the promises in the ES6 specification were based on, it defines a `.then() handler like this:

promise.then(onFulfilled, onRejected)

and then has this to say about it:

2.2.4. onFulfilled or onRejected must not be called until the execution context stack contains only platform code. [3.1].

And, then it defines platform code like this:

Here “platform code” means engine, environment, and promise implementation code. In practice, this requirement ensures that onFulfilled and onRejected execute asynchronously, after the event loop turn in which then is called, and with a fresh stack. This can be implemented with either a “macro-task” mechanism such as setTimeout or setImmediate, or with a “micro-task” mechanism such as MutationObserver or process.nextTick. Since the promise implementation is considered platform code, it may itself contain a task-scheduling queue or “trampoline” in which the handlers are called.

Basically what this means is that .then() handlers are called by inserting a task in the event loop that will not execute until the currently running Javascript finishes and returns control back to the interpreter (where it can retrieve the next event). So, thus any synchronous Javascript code you have after the .then() handler is installed will always run before the .then() handler is called.



来源:https://stackoverflow.com/questions/49214976/why-does-my-function-execute-before-my-promise-callback

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!