承诺在nodejs中没有实现

时间:2017-06-23 10:26:58

标签: javascript node.js

我正在研究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'并且根本不满足()。

有没有人对此有任何见解?我仍然很擅长承诺,并尝试在线搜索解决方案,但这是一个非常具体的问题,所以想在这里发帖。

2 个答案:

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