为什么我的函数会在我的 Promise 回调之前执行? [英] Why does my function execute before my promise callback?

查看:47
本文介绍了为什么我的函数会在我的 Promise 回调之前执行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么我的 Promise 之后调用的函数会在 Promise 回调之前执行?

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

我在 MDN 上读过这个,但没看懂

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

"在当前完成之前永远不会调用回调运行 JavaScript 事件循环."

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

我认为这意味着如果我在 resolve()reject() 之后有任何其他语句,它们将在调用回调之前执行.虽然,这似乎是一个不完整的理解.

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");
}

输出:

我的其他功能

成功

推荐答案

根据规范,promise .then().catch() 回调永远不会同步调用,但在事件循环的未来滴答声中被调用.这意味着您的其余同步代码始终在调用任何 .then() 处理程序之前运行.

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.

因此,您的 doOther() 函数在 doSuccess()doError() 被调用之前运行.

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

Promise 是这样设计的,因此无论 Promise 是立即解决还是在未来某个时间解决,promise .then() 处理程序都会以一致的时间被调用.如果允许同步 .then() 处理程序,那么调用代码要么必须知道它何时可能被同步调用,否则您很容易受到奇怪的计时错误的影响.

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.

在 ES6 规范中的 Promise 所基于的 Promises/A+ 规范中,它定义了一个 `.then() 处理程序是这样的:

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)

然后有话要说:

2.2.4.在执行上下文堆栈仅包含平台代码之前,不得调用 onFulfilled 或 onRejected.[3.1].

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:

这里的平台代码"是指引擎、环境和promise实现代码.在实践中,这个要求确保 onFulfilled 和 onRejected 异步执行,在调用 then 的事件循环之后,并使用新的堆栈.这可以通过宏任务"机制(例如 setTimeout 或 setImmediate)或微任务"机制(例如 MutationObserver 或 process.nextTick)来实现.由于promise实现被认为是平台代码,它本身可能包含一个任务调度队列或trampoline",在其中调用处理程序.

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.

基本上这意味着 .then() 处理程序通过在事件循环中插入一个任务来调用,直到当前运行的 Javascript 完成并将控制返回给解释器(其中它可以检索下一个事件).因此,安装 .then() 处理程序之后的任何同步 Javascript 代码将始终在调用 .then() 处理程序之前运行.

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.

这篇关于为什么我的函数会在我的 Promise 回调之前执行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆