在 Promise 链的中间传递一个额外的参数

Passing an extra parameter in the middle of a Promise chain

我需要在承诺链的中间加入一个 userID 参数(这是唯一需要它的承诺)。所有的承诺都应该以同步顺序执行。

旁注 - Whosebug 上的所有类似示例都有点不同 - 比如使用 lambda 函数(我使用声明的函数)。所以我仍然不太确定。

var initialize = function(userID) {
      var firstPromise = Module2.getFirstPromise();
          firstPromise.then(getSecondPromise)
         .then(getThirdPromise)                     
         .then(getFourthPromise)  //<----Fourth promise needs userID
         .then(getFifthPromise)
         .then(Utils.initializeComplete);
  }

所有的承诺都是这样的函数:

var thirdPromise = function() {
   return new Promise(function(resolve, reject) {
      //fetch data
        //On Return, Store it
         resolve() //Nothing needed to passed down from this promise
      });

    });

}

我正在尝试这个,它 "works",但我不确定我 "suppose" 是否就是这样处理这样的事情的。 :)

var initialize = function(userID) {
      var firstPromise = Module2.getFirstPromise();
          firstPromise.then(getSecondPromise)
         .then(getThirdPromise)                     
         .then(function(){ return fourthPromise(userID)})
         .then(getFourthPromise)
         .then(Utils.initializeComplete);
  }

注意:getFirstPromise 来自我代码中的另一个模块。不过,这对问题不重要 :)

假设 firstPromise 确实是一个 promise 但 secondPromise 等等实际上是函数 returning promises,那么是的,你所做的是你应该怎么做。 Here's a live example on Babel's REPL,看起来像这样:

function doSomething(userID) {
  getFirstPromise()
    .then(getSecondPromise)
    .then(getThirdPromise)
    .then(() => getFourthPromise(userID))
    // Or .then(function() { return getFourthPromise(userID); })
    .then(getFifthPromise)
    .catch(err => {
      console.log("Error: " + err.message);
    });
}
doSomething("foo");
function getFirstPromise() {
  console.log("getFirstPromise called");
  return new Promise(resolve => {
    setTimeout(() => {
      resolve("one");
    }, 0);
  });
}
// and then second, third, fourth (with user ID), and fifth

(如果不用箭头函数,直接用function形式代替即可)


注意上面示例中的 catch。除非你有非常好的理由不,如果你不return结果,承诺链应该总是有一个.catch

您的解决方案非常好。用具体的签名可能更容易理解。

如果你的 thirdPromise 不接受任何东西并且不 return 任何它的签名可能被写(伪代码假设 a -> b 是一个从 a 到 b 的函数)作为 _ -> Promise (_)。如果它 return 是某个值 a,它将是 _ -> Promise (a)。如果它采取了一些东西并且 return 编辑了一些东西,它可能是 a -> Promise (b)

因此,您可以将您的承诺链推理为函数取一些值并return包装在承诺中的其他一些值。但是,您的 fourthPromise 看起来不一样:

fourthPromise : UserId -> a -> Promise (b)

可以写成:

fourthPromise : UserId -> (a -> Promise (b))

它需要一个参数 ,然后 成为您可以链接的实际承诺。在某种程度上,它是一个承诺的模板。

如果你想要主函数中的普通 .then 链,请尝试将 getFourthPromise 编写为工厂函数

function getSomethingByUserID(userId) {
   return function() {
        return new Promise(function(resolve) {
            //your actual async job
            resolve('a result');
        });
   };
}

然后你会得到thens

的计划列表
 var firstPromise = Module2.getFirstPromise()
     .then(getSecondPromise)                   
     .then(getSomethingByUserID(userId))
     .then(Utils.initializeComplete);

不要忘记,如果您错过了向 getSomethingByUserID 提供 userId,它将无法工作。