我需要链接使用请求承诺的promise,所以它有点链接嵌套的promise。
想象一下代码:
const rp = require('request-promise');
function doStuff(){
for ( let i = 0; i <= 10; i++ ){
methodA();
}
};
function methodA(){
let options = {...};
rp(options)
.then(result => methodB(result))
.catch(err => console.log(err));
};
function methodB(resultA){
let options = {uri: resultA};
rp(options)
.then(result => methodC(resultA, result))
.catch(err => console.log(err));
};
function methodC(resultA, resultB){
//some calculations
};
在doStuff中我需要等待methodC的所有十次执行的结果并将它们收集到数组中。我试图将它链接起来:
function doStuff(){
for ( let i = 0; i <= 10; i++ ){
let promiseA = new Promise((resolve, reject) => {
resolve(methodA());
});
let promiseB = promiseA.then(result => methodB(result));
let promiseC = promiseB.then(result => methodC(promiseA.result, result));
Promise.all([promiseA, promiseB, promiseC]);
}
};
但是肯定它不会起作用,因为在methodA和methodB中我们有异步的HTTP请求。因此,promiseB的结果是未定义的。
这意味着,问题是:如果他们有嵌套的承诺,如何链接承诺?(以及如何收集结果?)
谢谢!
更新:链接承诺也没有多少帮助,因为在AB的数组之前返回1,但是期望的结果反之亦然:
function methodA(){
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('Resolved A');
resolve('A');
}, Math.random() * 2000);
});
return promise
.then(result => methodB(result))
.catch(err => console.log(err));
}
function methodB(resultA){
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('Resolved B');
resolve('B');
}, Math.random() * 2000);
});
return promise
.then(result => methodC(resultA, result))
.catch(err => console.log(err));
}
function methodC(resultA, resultB){
return resultA + resultB;
}
function doStuff() {
let promises = [];
for (let i = 0; i <= 10; i++){
promises.push(methodA());
}
Promise.all(promises).then(results => {
console.log(results);
});
return 1;
}
console.log(doStuff());
答案 0 :(得分:2)
您的每个职能都需要回复他们的承诺:
function methodA(){
let options = {...};
return rp(options)
.then(result => methodB(result))
.catch(err => console.log(err));
}
function methodB(resultA){
let options = {uri: resultA};
return rp(options)
.then(result => methodC(resultA, result))
.catch(err => console.log(err));
}
function methodC(resultA, resultB){
//some calculations
}
function doStuff() {
let promises = [];
for ( let i = 0; i <= 10; i++ ){
promises.push(methodA());
}
Promise.all(promises).then(...)
}
修改:我创建了一个测试示例,该示例在methodA
和methodB
中创建了承诺。每个承诺从0到2秒持续一段时间。它似乎有效:
function methodA(){
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('Resolved A');
resolve('A');
}, Math.random() * 2000);
});
return promise
.then(result => methodB(result))
.catch(err => console.log(err));
}
function methodB(resultA){
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('Resolved B');
resolve('B');
}, Math.random() * 2000);
});
return promise
.then(result => methodC(resultA, result))
.catch(err => console.log(err));
}
function methodC(resultA, resultB){
return resultA + resultB;
}
function doStuff() {
let promises = [];
for (let i = 0; i <= 10; i++){
promises.push(methodA());
}
return Promise.all(promises).then(results => {
console.log(results);
return 1;
});
}
doStuff().then(result => {
console.log(result);
});
答案 1 :(得分:0)
回答@Frank_Modica是可行的方法。
只想添加一下,如果您启用async/await
,就可以这样做。但它确实需要Babel
或Typescript
:
async function myMethod() {
const options = { }
try {
const result_a = await rp(options)
const result_b = await rp({ uri: result_a })
const result_c = ...
} catch(err) {
console.log(err)
}
}
for (let i = 0; i <= 10; i++) {
await myMethod();
}
答案 2 :(得分:-1)
必须轻微改为:
Promise.all([promiseA, promiseB, promiseC]).then([promiseD]);
同样在函数本身中,它必须是一个返回语句,以使它们链接。对于请求本身,只需添加:{async:false}
也可以使用:
var runSequence = require('run-sequence');
function methodA () {
return runSequence(
'promiseA',
'promiseB',
['promiseC1', 'promiseC2'],
'promiseD',
callback
);
}