我正在研究nodejs app,其中一部分是测试一些api调用,然后作为一个promise返回,然后执行另一个函数。
所以 - 我循环使用以下两个函数的promise数组:
覆盖所有apis的所有功能
function testAllApis(apiList, counter = 0){
return new Promise(function(fulfill, reject){
console.log(counter);
if(counter == apiList.length){
console.log('test1');
fulfill();
console.log('test2');
}
else {
testSingleApi(apiList[counter]).then(() => {
testAllApis(apiList, counter + 1);
}).catch((e) => {
console.log(e);
reject(e);
testAllApis(apiList, counter + 1);
})
}
})
}
每个阵列的功能
function testSingleApi(thisApi){
return new Promise(function(fulfill, reject){
var apiUrl = '/api/' + thisApi.substr(7).slice(0, -3) + '/testapi/';
var options = {
hostname: serverHost,
port: serverPort,
path: apiUrl,
method: 'GET',
};
var req = http.request(options, (res) => {
console.log(res.statusCode);
fulfill(res.statusCode);
});
req.on('error', (e) => {
reject(e.message);
});
req.end();
});
}
当我在终端中调用它时,它按预期运行,并且控制台记录我正在进行的api调用的成功代码(200),但是在第三个之后,当'counter'等于数组的长度时,它进入testAllApis函数中的if条件,控制台记录'test1',然后'test2'并且根本不满足()。
有没有人对此有任何见解?我仍然很擅长承诺,并尝试在线搜索解决方案,但这是一个非常具体的问题,所以想在这里发帖。
答案 0 :(得分:1)
使用reduce
顺序运行promises更容易:
var funcs = apiList.map((api) => testSingleApi(api));
var promiseSerial = (funcs) =>
funcs.reduce((promise, func) =>
promise.then(result = func().then(Array.prototype.concat.bind(result))),
Promise.resolve([]));
promiseSerial(promises)
.then(...)
.catch(...);
答案 1 :(得分:0)
如果使用async / await,可以避免递归并获得更清晰,更易于管理的代码。
如果您的节点支持async / await,您可以像这样重构逻辑:
async function testAllApis(apiList){
for(var i=0; i<apiList.length; i++)
console.log(await testSingleApi(apiList[i]));
}
testAllApis(apiList).then(function(){
console.log("all done at this point")
});
如果您的节点不支持async / await,您可以使用nsynjs module并更改您的代码:
nsynjs = require('nsynjs');
...
function testAllApis(apiList, testSingleApi){
for(var i=0; i<apiList.length; i++)
console.log(testSingleApi(apiList[i]).data);
}
nsynjs.run(testAllApis,{},apiList,testSingleApi,function(){
console.log("all done at this point");
})