Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/434.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript nodejs中循环的异步问题_Javascript_Node.js - Fatal编程技术网

Javascript nodejs中循环的异步问题

Javascript nodejs中循环的异步问题,javascript,node.js,Javascript,Node.js,我试图迭代一个项列表,并通过调用API对其执行一些操作,如以下示例所示: for (i = 0; i < arr.length; i++) { if (arr[i].id == 42) { api.requestAction(arr[i].id, function(error, response){ }); } } (i=0;i

我试图迭代一个项列表,并通过调用API对其执行一些操作,如以下示例所示:

  for (i = 0; i < arr.length; i++) {  
    if (arr[i].id == 42) {
      api.requestAction(arr[i].id, function(error, response){ });
    }
 }
(i=0;i if(arr[i].id==42){ requestAction(arr[i].id,函数(错误,响应){}); } } 问题是循环显然在所有请求完成和程序退出之前就结束了。我应该如何管理它?我看到了“承诺”方法,但不知道如何在这种情况下使用它,或者可能还有其他解决方案

提前谢谢你

你可以用。这是一个异步控制流库,为顺序循环、parralel中的循环和许多其他常见的流控制机制提供控制流,请查看

请参阅下面的代码,该代码假设变量“arr”在范围中的某个地方定义

npm异步安装

     var async = require("async");




     //Loop through each item, waiting for your
     //asyncronous function to finish before continuing
     //to move onto the next item in the array
     //NOTE: This does not loop sequentially, if you want that function with asyncjs then user eachSeries
     async.each(arr, 

         //Item is the current item being iterated over,
         //callback is the callback you call to finish the current iteration, it accepts an error and result parameter callback(error, result);
         function (item, callback) {
              api.requestAction(item.id, function(error, response){ 

                   //Check for any errors...     
                   if (error) return callback(error);
                   callback(null);
              });
         },
         function (err, result) {
              //You've now finished the loop

              if (err) {
                 //Do something, you passed an error object to
                 //in one of the loop's iterations
              }

              //No errors, move on with your code..
         });
你可以用。这是一个异步控制流库,为顺序循环、parralel中的循环和许多其他常见的流控制机制提供控制流,请查看

请参阅下面的代码,该代码假设变量“arr”在范围中的某个地方定义

npm异步安装

     var async = require("async");




     //Loop through each item, waiting for your
     //asyncronous function to finish before continuing
     //to move onto the next item in the array
     //NOTE: This does not loop sequentially, if you want that function with asyncjs then user eachSeries
     async.each(arr, 

         //Item is the current item being iterated over,
         //callback is the callback you call to finish the current iteration, it accepts an error and result parameter callback(error, result);
         function (item, callback) {
              api.requestAction(item.id, function(error, response){ 

                   //Check for any errors...     
                   if (error) return callback(error);
                   callback(null);
              });
         },
         function (err, result) {
              //You've now finished the loop

              if (err) {
                 //Do something, you passed an error object to
                 //in one of the loop's iterations
              }

              //No errors, move on with your code..
         });
使用(promisify http api),您可以与async/await一起停止for循环,直到完成为止,但这需要添加带有
--harmony async await
标志的节点v6+

const fetch = require('node-fetch')

async function foo() {
  for (let item of arr) {
    if (item.id == 42) {
      let res = await fetch(url)
      let body = await res.text()
      console.log(body)
    }
  }
  console.log('done (after request)')
}
现在,每次在函数前面添加async关键字时,它都会返回一个承诺,即在完成所有操作后解析/拒绝

foo().then(done, fail)

或者,如果您不想安装节点获取,您可以将您的api fn封装在一个承诺中

await new Promise((rs, rj) => {
  api.requestAction(arr[i].id, function(error, response){
    error ? rj(error) : rs(response)
  })
}) 
使用(promisify http api),您可以与async/await一起停止for循环,直到完成为止,但这需要添加带有
--harmony async await
标志的节点v6+

const fetch = require('node-fetch')

async function foo() {
  for (let item of arr) {
    if (item.id == 42) {
      let res = await fetch(url)
      let body = await res.text()
      console.log(body)
    }
  }
  console.log('done (after request)')
}
现在,每次在函数前面添加async关键字时,它都会返回一个承诺,即在完成所有操作后解析/拒绝

foo().then(done, fail)

或者,如果您不想安装节点获取,您可以将您的api fn封装在一个承诺中

await new Promise((rs, rj) => {
  api.requestAction(arr[i].id, function(error, response){
    error ? rj(error) : rs(response)
  })
}) 

使用蓝鸟承诺:

var Promise = require('bluebird');

Promise.map(arrayOfIds, function(item){
  return api.requestAction(item);
})
.then(function(response){
 // all the requests are resolved here
})

如果您希望按顺序执行ids,请使用
Promise.mapSeries
(在等待任务完成时速度较慢)

使用蓝鸟承诺:

var Promise = require('bluebird');

Promise.map(arrayOfIds, function(item){
  return api.requestAction(item);
})
.then(function(response){
 // all the requests are resolved here
})
如果您希望按顺序执行ids,请使用
Promise.mapSeries
(在等待任务完成时速度较慢)

安装

代码

//require npm
var Promise = require("bluebird");

//code
//"promisify" converts traditional callback function into a Promise based function
var _requestAction = Promise.promisify(api.requestAction);

//loop over array
Promise.map(arr, function (value) {
    if (value.id == 42) {
        //async request
        return _requestAction(value.id).then(function (_result) {
            //success
            console.log(_result);
        }).catch(function (e) {
            //error
            console.error(e);
        });
    }
});
安装

代码

//require npm
var Promise = require("bluebird");

//code
//"promisify" converts traditional callback function into a Promise based function
var _requestAction = Promise.promisify(api.requestAction);

//loop over array
Promise.map(arr, function (value) {
    if (value.id == 42) {
        //async request
        return _requestAction(value.id).then(function (_result) {
            //success
            console.log(_result);
        }).catch(function (e) {
            //error
            console.error(e);
        });
    }
});

你在使用任何
Promise
库吗?不,我没有使用它,因为我真的不知道如何处理它。@shaharyar从OP:我看到了“Promise”方法,但不知道如何在这种情况下使用它,或者可能有其他解决方案。如果我回答Promise,你会同意吗?因为最终你需要使用它。你不能完全依靠回调来生存。本例使用承诺和循环来做一些事情。您是否使用了任何
Promise
库?不,我没有使用它,因为我不知道如何处理它。@shaharyar,来自OP:我看到了“Promise”方法,但不知道在这种情况下如何使用它,或者可能有其他解决方案。如果我回答Promise,您会同意吗?因为最终你需要使用它。你不能完全依靠回调来生存。这个例子使用承诺和循环来做一些事情。你的解决方案有意义,我没有看到他在停止循环,谢谢你提到你的解决方案有意义,我没有看到他在停止循环,谢谢你提到var\u requestAction=promisify.promisify(api.requestAction);这里的api.requestAction是一个函数调用。不,它是将其转换为
Promise
。我添加了explaution.var _requestAction=promisify.promisify(api.requestAction);这里的api.requestAction是一个函数调用。不,它是将其转换为
Promise
。我已经添加了解释。为什么要将其包装在一个闭包中?习惯的力量,刚刚移除了封装闭包:)我通常会将任何片段包装在闭包中,这样我就可以复制和粘贴代码,确保代码不会破坏目标脚本中的任何其他内容。虽然答案的可读性很好!为什么要用闭包来包装它?习惯的力量,刚刚移除了封装闭包:)我通常会用闭包来包装任何代码片段,这样我就可以复制和粘贴代码,确保代码不会破坏目标脚本中的任何其他内容。虽然答案的可读性很好!