【问题标题】:NodeJS Making a for loop asynchronousNodeJS 使 for 循环异步
【发布时间】:2017-08-29 15:42:43
【问题描述】:

我的 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!');
});

【问题讨论】:

  • 已经尝试使用具有实际延迟的 setTimeouts 和 setTimeout 0 技巧。
  • @Paul 您提出的问题是关于如何阻止长时间运行的任务占用线程并使其他任务挨饿。这个问题似乎是关于等待循环的每次迭代完成异步操作。
  • 正是 Apsillers 所说的 ^^^。那里有一个解决方案导致一些代码可能解决了我的问题,但它没有做太多:/

标签: node.js


【解决方案1】:

您可以将我的“ploop”函数与 Promise 一起使用。 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

【讨论】:

  • 我现在就试试这个,谢谢,必须移动一些代码来试试这个
  • 当我设置一切时,我设法找到了一个稍微不同的解决方案,所以我现在很好,但是你引导我找到了解决方案,所以谢谢你:) 在我处理完我的代码后,我'我也会尝试这个解决方案。花了我一段时间,因为我以前没有处理过承诺。再次感谢
猜你喜欢
  • 2019-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-19
  • 1970-01-01
  • 2015-04-11
  • 1970-01-01
相关资源
最近更新 更多