繁体   English   中英

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

[英]How to wait for each iteration in for loop and return response as API response in nodeJS

我正在使用for循环遍历元素数组,并在for循环内使用不同的参数调用相同的函数。 这是我的代码:

exports.listTopSongs = function(query) {
    return new Promise(function(resolve, reject) {
        var str = query.split(","), category,
        for(var i=0; i<str.length; i++) {
           sampleFn(str[i], 'sample', resolve, reject);
        }
    });
};

function sampleFn(lang, cat, resolve, reject) {
        client.on("error", function (err) {
            console.log(err);
            var err = new Error('Exception in redis client connection')
            reject(err);                                
        });
        client.keys(lang, function (err, keys){
            if (err) return console.log(err);
            if(keys.length != 0) {
                client.hgetall(keys, function (error, value) {
                    var objects = Object.keys(value);
                    result['title'] = lang;
                    result[cat] = [];
                    var x =0;
                    for(x; x<objects.length; x++) {
                        var val = objects[x];
                            User.findAll({attributes: ['X', 'Y', 'Z'],
                                where: {
                                    A: val
                                }
                            }).then(data => {
                                if(data != null) {
                                    //some actions with data and stored it seperately in a Json array
                                    if(result[cat].length == objects.length) {
                                        resolve(result);
                                    }
                                } else {
                                    console.log(""+cat+" is not avilable for this value "+data.dataValues['X']);
                                }
                            });
                    }
               });
         });
   }

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

我使用了node-async-loop。 但是它使用了下一个,并且在使用该程序包时我无法发送参数。 请帮我

异步提供了允许的控制流方法。

使用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');
    }
});

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

 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 参见thenable

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

 //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)) 

由于您正在使用诺言,因此您可以执行以下操作

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 ;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM