NodeJS使for循环异步

时间:2017-08-29 15:42:44

标签: node.js

我在使用NodeJS程序时遇到了一些麻烦。

所以我的for循环应该起作用的方式是,它应该迭代我的SQL数据库中的索引,并且在for循环的每次运行中,它应该调用另一个函数来生成一个GET请求。

它实际上做的是它遍历我的所有索引,然后一次/非常快地完成每个GET请求,这最终使我不再需要再进行API调用。我尝试使用setTimeout,但这不起作用,因为它只是迭代到下一个索引,并且值最终未定义。

还尝试了回调,但它没有改变任何东西。我试着调查异步,但是我真的无法理解我应该做的事情。也只是一个注释,实际上没有任何东西被退回。在我的其他功能中,我只是更新我的SQL DB。我只需要for循环就可以在每次运行时进行API调用,并且只有在完成后才会继续。

    function callGet() {

    var mysql = require('mysql');
    var con = mysql.createConnection({
        host: "localhost",
        user: "USERNAME",
        password: "PASSWORD",
        database: "sys"
    });

    con.query("SELECT nameAlone FROM testDB", function(err, result, fields) {

       var i;

        for(i = 0; i < result.length; i++){

        var name = result[i].nameAlone;

        var options = {
            method: 'GET',
            url: 'site.com',
            qs: {
                key: 'MYKEY',
                page_size: 10,
                intent: 0,
                itemName: name
            },
            headers: {
                'postman-token': postman-token,
                'cache-control': 'no-cache'
            }
        };  
        getListing(options,result, i);                  //Only being called after the for loop iterates through all of result.length
}
    });
}

发生了什么事的一个例子,让我们说for循环从0-2开始迭代,每次运行都会调用一个打印出名字的函数。 而不是

index:0, name:Chris, index:1, name:Tony, index:2, name:John

打印出来:

index:0, index:1, index:2, name:Chris, name:Tony, name:John

提前感谢您的帮助。

编辑:我已经尝试了在建议的重复问题中应用于我的问题的所有答案。试图弄清楚其中一个答案,但不太确定它是否会起作用。

Edit2:那里的所有解决方案都没有用。

Edit3(解决方案):如果有人想要一个非常简单的解决方案,我发现这个包非常容易设置:https://github.com/nathan818fr/async-loop

我所要做的就是使用我的索引创建一个数组并设置asyncLoop如下:

asyncLoop(indices, function (item, next)
{
    var name = result[item].nameAlone;
    var options = {
        method: 'GET',
        url: 'site.com',
        qs: {
            key: 'MYKEY',
            page_size: 10,
            intent: 0,
            itemName: name
        },
        headers: {
            'postman-token': postman-token,
            'cache-control': 'no-cache'
        }
    };  

    getListing(options,result, item);
    next();
}, function ()
{
    console.log('Finished!');
});

1 个答案:

答案 0 :(得分:0)

您可以使用我的“ploop&#39;承诺的功能。 ploop基本上采用一个返回promise的函数,函数所需的任何参数以及一个决定ploop是否完成的函数。你没有填写第四个参数。下面是一个使用ploop绘制随机数的示例,直到找到数字4:

// Function that returns a promise
var searchForNumber = function(number) {
    return new Promise(function(resolve, reject) {
      setTimeout(function() {
        var min = 1;
        var max = 10;
        var val = Math.floor(Math.random()*(max-min+1)+min);

        console.log('Value is: ' + val.toString());        

        return resolve(val);        
      }, 1000);
    });
};

// fn     : function that should return a promise.
// args   : the arguments that should be passed to fn.
// donefn : function that should check the result of the promise
//    and return true to indicate whether ploop should stop or not.
// promise: A promise value that is used internally by ploop and should never 
//    be passed in by the caller of ploop.
var ploop = function(fn, args, donefn, promise) {
    return (promise || Promise.resolve(true))    
      .then(function() {
          return(fn.apply(null, args));
      })
      .then(function(result) {
        var finished = donefn(result);
        if(finished === true){
           return result;
        } else {
          return ploop(fn, args, donefn, promise);
        }
    });
};

var searchFor = 4;

var donefn = function(result) {
  return result == searchFor;
};

console.log('Searching for: ' + searchFor);
ploop(searchForNumber, [searchFor], donefn)
  .then(function(val) {
    console.log('Finally found! ' + val.toString());  
    process.exit(0);
  })
  .catch(function(err) {
    process.exit(1);
  });

除了ploop函数本身之外的所有内容都是示例代码。这是演示:

http://jsbin.com/woxetos/edit?js,console

相关问题