Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么我的函数在我的承诺回调之前执行?_Javascript_Promise - Fatal编程技术网

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

Javascript 为什么我的函数在我的承诺回调之前执行?,javascript,promise,Javascript,Promise,为什么在我的承诺之后调用的函数在承诺的回调之前执行 我在MDN上读到了这篇文章,但不明白 “在当前任务完成之前,永远不会调用回调 运行JavaScript事件循环。“ 我认为这意味着如果在resolve()或reject()之后有任何其他语句,它们将在调用回调之前执行。不过,这似乎是一个不完整的理解 function myFunction() { return new Promise( function(resolve, reject) { const err = false;

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

我在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");
}
输出:

我的其他功能


Success

根据规范,promise
.then()
.catch()
回调永远不会同步调用,而是在事件循环的未来勾选时调用。这意味着其余的同步代码总是在调用任何
处理程序之前运行

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

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

在ES6规范中的承诺所基于的示例中,它定义了一个`.then()处理程序,如下所示:

promise.then(onFulfilled, onRejected)
然后有这样一个说法:

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

然后,它定义了如下的平台代码:

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


基本上,这意味着通过在事件循环中插入一个任务来调用
.then()
处理程序,该任务在当前运行的Javascript完成并将控制权返回给解释器(解释器可以在解释器中检索下一个事件)之前不会执行。因此,在安装
.then()
处理程序之后的任何同步Javascript代码都将始终在调用
.then()
处理程序之前运行
doOther
在当前运行中执行,因此在此之前不会调用回调。您的问题适用于promise
。then()
回调,而不是一般的回调。有许多回调是同步调用的,例如传递给
array.filter()
的内容。感谢您提供了非常详细的答案。