承诺,一切() . 然后()解决?

使用 Node 4. x。当你有一个 Promise.all(promises).then()什么是正确的方法来解决数据,并传递给下一个 .then()

我想这样做:

Promise.all(promises).then(function(data){
// Do something with the data here
}).then(function(data){
// Do more stuff here
});

但是我不知道如何把数据传送到第二个 .then()。我不能在第一个 .then()中使用 resolve(...)。我发现我可以做到:

return Promise.all(promises).then(function(data){
// Do something with the data here
return data;
}).then(function(data){
// Do more stuff here
});

但这似乎不是正确的做法... ... 什么是正确的做法?

219041 次浏览

But that doesn't seem like the proper way to do it..

That is indeed the proper way to do it (or at least a proper way to do it). This is a key aspect of promises, they're a pipeline, and the data can be massaged by the various handlers in the pipeline.

Example:

const promises = [
new Promise(resolve => setTimeout(resolve, 0, 1)),
new Promise(resolve => setTimeout(resolve, 0, 2))
];
Promise.all(promises)
.then(data => {
console.log("First handler", data);
return data.map(entry => entry * 10);
})
.then(data => {
console.log("Second handler", data);
});

(catch handler omitted for brevity. In production code, always either propagate the promise, or handle rejection.)

The output we see from that is:

First handler [1,2]
Second handler [10,20]

...because the first handler gets the resolution of the two promises (1 and 2) as an array, and then creates a new array with each of those multiplied by 10 and returns it. The second handler gets what the first handler returned.

If the additional work you're doing is synchronous, you can also put it in the first handler:

Example:

const promises = [
new Promise(resolve => setTimeout(resolve, 0, 1)),
new Promise(resolve => setTimeout(resolve, 0, 2))
];
Promise.all(promises)
.then(data => {
console.log("Initial data", data);
data = data.map(entry => entry * 10);
console.log("Updated data", data);
return data;
});

...but if it's asynchronous you won't want to do that as it ends up getting nested, and the nesting can quickly get out of hand.

Today NodeJS supports new async/await syntax. This is an easy syntax and makes the life much easier

async function process(promises) { // must be an async function
let x = await Promise.all(promises);  // now x will be an array
x = x.map( tmp => tmp * 10);              // proccessing the data.
}


const promises = [
new Promise(resolve => setTimeout(resolve, 0, 1)),
new Promise(resolve => setTimeout(resolve, 0, 2))
];


process(promises)

Learn more:

Your return data approach is correct, that's an example of promise chaining. If you return a promise from your .then() callback, JavaScript will resolve that promise and pass the data to the next then() callback.

Just be careful and make sure you handle errors with .catch(). Promise.all() rejects as soon as one of the promises in the array rejects.