如何等待for循环中的每次迭代并将返回响应作为nodeJS中的API响应

时间:2017-09-19 07:07:59

标签: javascript node.js asynchronous nodes node-modules

我使用for循环迭代一个元素数组,并在for循环中调用具有不同参数的相同函数。这是我的代码:

(1,6)

这里它不会等待第一次迭代的完成。它只是在完成第一次迭代功能之前异步运行。我需要返回结果:[{1,2},{3,4}]。但它无缝运行并在完成所有操作之前返回空或只有一个对象。如何解决它。

我使用了node-async-loop。但它使用next,我无法在使用该包时发送我的参数。请帮帮我

3 个答案:

答案 0 :(得分:1)

Async提供了允许这样做的控制流方法。

使用async.each

async.each(openFiles, function(file, callback) {

    // Perform operation on file here.
    console.log('Processing file ' + file);

    if( file.length > 32 ) {
      console.log('This file name is too long');
      callback('File name too long');
    } else {
      // Do work to process file here
      console.log('File processed');
      callback();
    }
}, function(err) {
    // if any of the file processing produced an error, err would equal that error
    if( err ) {
      // One of the iterations produced an error.
      // All processing will now stop.
      console.log('A file failed to process');
    } else {
      console.log('All files have been processed successfully');
    }
});

答案 1 :(得分:0)

如果您不想使用库,可以自己编写代码。这也很有启发性。我接受了你的问题并编写了一个虚拟的异步循环:

function listTopSongs(query) {
    return new Promise(async(resolve, reject) => { //add async here in order to do asynchronous calls
        const str = query.split(",") //str is const, and the other variable was not used anyway
        
        for( let i = 0;i < str.length; i++) {
            const planet = await sampleFn(str[i], 'sample', resolve, reject)
            console.log(planet)
        }
    });
};

function sampleFn(a, b, c, d) {
    return fetch(`https://swapi.co/api/planets/${a}/`)
        .then(r => r.json())
        .then(rjson => (a + " : " + rjson.name))
}

listTopSongs("1,2,3,4,5,6,7,8,9")

我使用了一些虚拟星球大战API来伪造一个长期的承诺,但它应该与你的sampleFn一起使用。要小心,如果你有像网络调用那样非常非常慢。

编辑:我运行了你的代码,我注意到有一些错误:你的承诺没有解决方案,所以它不是那么好(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve 看得见

这是一个完全有效的代码。好的部分:不需要库,没有依赖。

//for node.js, use node-fetch :
//const fetch = require("node-fetch")

function listTopSongs(query) {
    return new Promise(async(resolve, reject) => { //add async here in order to do asynchronous calls
        const str = query.split(",") //str is const, and the other variable was not used anyway
        const planets = []
        for (let i = 0; i < str.length; i++) {
            const planet = await sampleFn(i + 1, str[i], resolve, reject)
            planets[i] = planet
            console.log(planet)
        }
        resolve(planets)
    });
};

function sampleFn(a, b, c, d) {
    return fetch(`https://swapi.co/api/planets/${a}/`)
        .then(r => r.json())
        .then(rjson => (a + b + " : " + rjson.name))
}

listTopSongs("a,b,c,d").then(planets => console.log(planets))

答案 2 :(得分:0)

既然你正在使用诺言,你可以做这样的事情

exports.listTopSongs = function(query) {
    return Promise.resolve(true).then(function(){
        var str = query.split(",");
        var promises = str.map(function(s){
            return sampleFn(str[i], 'sample');
        });
        return Promise.all(promises);
    }).then(function(results){
       //whatever you want to do with the result
    });
};

为此,您必须将 sampleFn 更改为不依赖于外部解析和拒绝功能。我没有看到使用外部解决和拒绝的原因。为什么不使用 Promise.Resolve,Promise.Reject ;