用q.js链接承诺

时间:2013-11-19 14:51:22

标签: javascript promise q

我正在试图理解承诺链是如何工作的。我正在使用q.js。这就是我正在玩的东西。

var Q = require("q"); // npm install q

// the function Q(value) returns a fulfilled promise with the value... I think.
Q(1).then(Q(2)).then(Q(3)).then(Q(4)).then(function(n) {
    console.log(n);
});

Q(1).then(function(n) {
    return Q(2);
}).then(function(n) {
    return Q(3);
}).then(function(n) {
    return Q(4);
}).then(function(n) {
    console.log("done: " + n);
});

我的问题基本上归结为为什么第一个记录1,而后者记录我期望的内容并基本记录1到4.我希望第一个记录4而不是1

我真的只是希望能够有一些返回promises的方法,然后像瀑布一样将它们链接在一起 - 我想我可以使用async和瀑布,但只是想知道这是否可以实现了承诺。

2 个答案:

答案 0 :(得分:16)

这是因为then并不期望另一个承诺作为论据。相反,它需要处理程序函数回调和/或 errback ,前者是您在第二个示例中传递的。 Indeed any argument that is not a function is simply ignored

From the docs

  

如果在处理程序中返回一个值,则将完成outputPromise。

     

如果在处理程序中抛出异常,则outputPromise将被拒绝。

     

如果在处理程序中返回一个promise,则outputPromise将“成为”该promise。能够成为新承诺对于管理延迟,组合结果或从错误中恢复非常有用。

所以是的,可以完成链接承诺。你在第二个例子中正确地做到了。

这里通过实现承诺的人为设想的示例可能会使链接承诺的工作看起来过于冗长,但在实际使用中,您通常会将承诺链接起来,因为您对它们的返回值感兴趣,例如:

somethingAsync().then(function (n) {
  return somethingElseAsync(n);
})
.then(function (n) {
  return somethingElseAsync(n);
})
.then(function (result) {
  // ...
})

(实际上这个镜像async.waterfall。如果您只想按顺序调用一系列异步函数而不考虑其结果,可以使用async.series

答案 1 :(得分:5)

我知道javascript没有静态类型,但你需要在这里考虑类型。

Q(1);                             // has type Promise[Int]
function (n) { return Q(2); }     // has type Int => Promise[Int]

Q.then需要第二个。