承诺不履行在nodejs

我正在使用nodejs应用程序,其中的一部分testing一些API调用,然后作为承诺返回,然后执行另一个函数。

所以 – 我通过一系列的promise来循环下面两个函数:

覆盖所有apis的所有function

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

每个arrays的function

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

当我在terminal中调用它时,它的function如预期的那样,控制台logging我正在创build的api调用的成功代码(200),但是在第三个调用之后,当'counter'等于数组的长度时,进入testAllApis函数中的if条件,控制台logging“test1”,然后是“test2”,根本不符合()。

有没有人有任何见解? 我对承诺还是比较陌生,并试图在网上寻找一个解决scheme,但这是一个相当具体的问题,所以想在这里发表。

按顺序使用reduce可以更容易地运行promise:

 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(...); 

如果使用async / await,则可以避免recursion,并获得更简洁,更易于pipe理的代码。

如果你的节点支持asynchronous/等待,你可以像这样重构逻辑:

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

如果你的节点不支持asynchronous/等待,你可以使用nsynjs模块,并像这样改变你的代码:

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