代码在Promise中异步执行的地方在哪里?

时间:2017-04-23 10:46:12

标签: javascript asynchronous promise es6-promise

以下javascript函数来自You Don't Know JS: Async & Performance。根据我的理解,第一条评论// start doing something that could take a while具有误导性。可能异步完成某些事情的代码部分是在传递给Promise构造函数的函数中。

function foo(x) {
    // start doing something that could take a while *misleading comment*

    // construct and return a promise
    return new Promise( /* executor */ function(resolve,reject){
        // eventually, call `resolve(..)` or `reject(..)`,
        // which are the resolution callbacks for
        // the promise.
    } );
}

我会用以下方式修复它:

function foo(x) {
    // construct and return a promise
    return new Promise( /* executor */ function(resolve,reject){
        // start doing something that could take a while
        // then foo returns the newly created Promise
        // eventually, call `resolve(..)` or `reject(..)`,
        // which are the resolution callbacks for
        // the promise.
    } );
}

2 个答案:

答案 0 :(得分:2)

是的,这应该是固定的(感谢提交this issue)。

这让我想起了difference between the deferred pattern and the revealing constructor pattern。在promise构造函数回调中启动异步任务有两个好处:

  • 如果它同步抛出(例如语法错误,方法调用中的拼写错误等),异常将被隐式捕获并拒绝承诺
  • resolvereject回调已经在作为回调传递给异步进程的范围内。

答案 1 :(得分:1)

答案是:在promise中异步执行代码。 *

虽然您展示的第二种形式稍微有点优势,但这完全是因为它更一致地处理错误(期望呼叫者处理异常和拒绝是不好的形式)。

解决您的主要困惑:promise executor函数同步运行。来自MDN

  

执行函数由Promise实现立即执行,传递resolve和reject函数(在Promise构造函数甚至返回创建的对象之前调用执行程序)。

spec

  

从执行程序函数返回并不意味着延迟操作已经完成,而只是表示已接受最终执行延迟操作的请求。

您可以启动任何最终调用resolvereject的异步操作:



new Promise(resolve => setTimeout(resolve, 2000))
  .then(() => console.log("Async"));

console.log("Sync");




最重要的是,Promise构造函数仅用于包装不支持promises的旧函数。 Don't use it for anything else

*)实际上,.then保证传递给它的函数不会立即运行,所以我的第一个语句并不完全正确。他们可以运行的最快是在事件循环的同一次运行结束时,在一个微任务队列中。几乎没有你想要的。