用q.js链接承诺

chaining promises with q.js

本文关键字:承诺 链接 js      更新时间:2023-09-26

我正在努力了解承诺链接是如何工作的。我用的是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

我真的只是想拥有一些返回promise的方法,然后以瀑布式的方式将它们链接在一起——我想我可以使用async和瀑布,但我只是想知道这是否可以通过promise实现。

这是因为then不期望另一个promise作为参数。相反,它需要处理程序函数回调和/或错误返回,您在第二个示例中传递的是前者。事实上,任何而不是函数的参数都会被忽略。

来自文档:

如果在处理程序中返回一个值,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

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

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

Q.then需要第二个。