繁体   English   中英

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

[英]Why does my function execute before my promise callback?

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

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

“在 JavaScript 事件循环的当前运行完成之前,永远不会调用回调。”

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

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 .catch() .then().catch()回调永远不会同步调用,而是在事件循环的未来滴答上调用。 这意味着您的同步代码的其余部分始终在调用任何.then()处理程序之前运行。

因此,您的doOther()函数在doSuccess()doError()之前运行。

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

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

promise.then(onFulfilled, onRejected)

然后有话要说:

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

然后它定义了这样的平台代码:

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM