chaining promises with q.js

扶醉桌前 提交于 2019-12-21 07:26:18

问题


I'm trying to understand how promise chaining works. I'm using q.js. Here's what I'm playing with.

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);
});

My question basically boils down to why does the first one log 1 while the latter one logs what I would expect and basically logs 1 through 4. I had hoped the first one would log 4 instead of 1.

I really just wanted to be able to have some methods that return promises and then chain them together in a waterfall like fashion - I guess I could use async and waterfall, but just wanted to know if this could be achieved w/ promises.


回答1:


It's because then doesn't expect another promise as an argument. Rather it expects handler functions, an callback and/or an errback, the former you are passing in your 2nd example. Indeed any argument that is not a function is simply ignored.

From the docs:

If you return a value in a handler, outputPromise will get fulfilled.

If you throw an exception in a handler, outputPromise will get rejected.

If you return a promise in a handler, outputPromise will “become” that promise. Being able to become a new promise is useful for managing delays, combining results, or recovering from errors.

So yes, chaining promises can be done. You're doing it right in your 2nd example.

It's possible that the contrived example here of passing fulfilled promises makes the way chaining promises works seem overly verbose, but in real world usage, you typically chain promises because you're interested in their return values, e.g.:

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

(Actually this mirrors async.waterfall. If you just wanted to call a series of async functions in order with no regards to their results you could use async.series)




回答2:


I know javascript doesn't have static types, but you need to think about types here.

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

Q.then needs the second.



来源:https://stackoverflow.com/questions/20074685/chaining-promises-with-q-js

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!