为什么承诺链可以被夷为平地?

时间:2017-04-28 03:12:20

标签: javascript promise

以下代码包含两种承诺链,似乎它们是等价的,但我不明白为什么它们是等价的。我认为它像2 *(3 + 4)= 2 * 3 + 4,这是不正确的。

// example1
runAsync1()
.then(function(data1){
    return runAsync2()
    .then(function(data2){
        return runAsync3(); 
    })
})
.then(function(data3){
    console.log(data3);
});

// example 2
runAsync1()
.then(function(data1){
    return runAsync2();
}).then(function(data2){
    return runAsync3();  
}).then(function(data3){
    console.log(data3);
});

2 个答案:

答案 0 :(得分:1)

也许一些牙箍可以帮助你更好地理解这一点。 (注意:这与你的完全相同,只是在返回时有一组额外的括号)

// example1
runAsync1()
.then(function(data1){
    return (
        runAsync2()
        .then(function(data2){
            return runAsync3(); 
        })
    )
})
.then(function(data3){
    console.log(data3);
});

那么这里发生了什么,

    .then 上调用
  1. runAsynch1() 然后在.then上调用
  2. runAsynch2(),返回runAsynch3()(此返回一直沿着返回链继续)
  3. 最后在返回的.then
  4. 上调用runAsynch3()

    如您所见,这与示例2中的情况完全相同

    // example 2
    runAsync1()
    .then(function(data1){
        return runAsync2();
    }).then(function(data2){
        return runAsync3();  
    }).then(function(data3){
        console.log(data3);
    });
    

答案 1 :(得分:0)

这是一个特定于实现的,但不管具体细节如何都在then

然后做了几件事。 TL; DR是then订阅返回的promise链,但下面是更接近promise的内容的例子。

首先是:
“承诺是否仍然未决?然后安排这些回调以供日后使用;否则,安排此回调在下一个刻度线(setTimeout(handle, 0))上运行。返回一个解析/拒绝最终值的新承诺。”

// basically accurate-ish
then (onSuccess, onError) {
  return new Promise((resolveNext, rejectNext) => {
    if (myPromiseIsDone) {
      // I already have the value; run the next step ASAP
      // this is ugly, but hopefully it proves a point
      runOnNextTick(onSuccess, onError, promiseResult, resolveNext, rejectNext);
    } else {
      // I don't have a result yet; come back when it's ready
      scheduleWhenDone(onSuccess, onError, resolveNext, rejectNext);
    }
  });
}

第二个是你的答案所在:
“运行处理程序。从传递给then的回调中获取返回值。返回值是否为Thenable对象(具有then方法)?然后调用then并传递在控制我的承诺的解决/拒绝函数中...否则,根据它是抛出还是返回来相应地解决/拒绝。“

// entirely subjective and implementation-specific,
// but the algorithm is almost spec-compliant
handleSuccess (onSuccess, resolveNext, rejectNext, value) {
  if (!onSuccess) {
    // if they didn't give me a `then(callback)`,
    // just pass the value to the next promise
    resolveNext(value);
    return;
  }
  try {
    // I'm running the `then(callback)` here
    const result = onSuccess(value);
    if (hasThenMethod(result)) {
      // it's promise-like, subscribe
      result.then(resolveNext, rejectNext);
    } else {
      resolveNext(result);
    }
  } catch (err) {
    // something blew up, while trying to succeed, so fail
    rejectNext(err);
  }
}

拒绝看起来很相似。

因此外部then订阅内部then

如果你想进入函数式编程,ES6 Promise 几乎一个monad。
不同之处在于monad会强制你使用不同的方法,告诉它链接到返回的promise,而不是自动执行。
then与数组上的map基本相同。然后调用它,传递一个获取值的函数,并返回一个带有转换值的新promise。

所以monadic承诺可能是mapchain,或thenchain,其中chain几乎完全相同但是说“嘿,then,这个回调将返回一个承诺;订阅那个回复,以便你把它弄平,而不是返回一个承诺值的承诺”。

这几乎只需要成为一个单子。

希望一切都有所帮助。