Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/469.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,在将对象数组(objects[])保存到DB之前,我尝试进行一些检查(使用mongoose的mongoDB): 这些对象已按日期排序,因此对象[0]。日期低于对象[1]。日期 每个对象都应检查上次保存的相关对象是否具有不同的值(以避免两次保存相同的信息)。这意味着我必须在每次保存之前查询数据库,以进行检查,并且必须存储这些对象中的每一个,以便能够使用正确的对象进行检查。如果对象未按顺序存储,则最后保存的相关对象可能不是正确的对象 深入解释: let testArray = [0, 1, 2,

在将对象数组(objects[])保存到DB之前,我尝试进行一些检查(使用mongoose的mongoDB):

  • 这些对象已按日期排序,因此对象[0]。日期低于对象[1]。日期
  • 每个对象都应检查上次保存的相关对象是否具有不同的值(以避免两次保存相同的信息)。这意味着我必须在每次保存之前查询数据库,以进行检查,并且必须存储这些对象中的每一个,以便能够使用正确的对象进行检查。如果对象未按顺序存储,则最后保存的相关对象可能不是正确的对象
深入解释:

let testArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

testArray.asyncForEach(function(element) {
  setTimeout(() => {
    console.log(element);
  }, Math.random() * 500);
});
HTTP请求被发送到API。它返回一个对象数组(按日期排序),我要处理这些对象并将其保存在我的MongoDB上(使用mongoose)。我必须遍历所有这些对象,对于每个对象:

  • 查找存储在DB上的前一个相关对象(可能是该数组中的一个)
  • 检查“已存储”和要保存的对象之间的一些值,以评估新对象是否必须保存或可以丢弃
  • 保存或放弃它,然后跳转到下一个迭代
等待每个迭代完成非常重要,因为:

  • 数组中的项必须按顺序存储在数据库中:首先是那些日期较低的项,因为每个项都可以被稍后存储的日期较高的对象修改
  • 如果下一次迭代在上一次迭代完成之前开始,则搜索上一个对象的查询无法找到它(如果它尚未存储)
已尝试:

let testArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

testArray.asyncForEach(function(element) {
  setTimeout(() => {
    console.log(element);
  }, Math.random() * 500);
});
在forEach/for循环上使用promissions或async/await只能使迭代异步,但它会同时启动所有迭代

我曾尝试在forEach/for循环中使用async/await函数,甚至创建了自己的asyncfeach函数,如下所示,但这些都不起作用:

Array.prototype.asyncForEach = function(fn) {
  return this.reduce(
   (promise, n) => promise.then(() => fn(n)),
  Promise.resolve()
 );
};
测试功能:

let testArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

testArray.asyncForEach(function(element) {
  setTimeout(() => {
    console.log(element);
  }, Math.random() * 500);
});
提供的示例应显示每种情况下订单上的数字。如果内部函数(示例中的setTimeout)应该返回一个承诺,则这不是问题

我认为我需要的是一个循环,它在迭代之间等待一些函数/承诺,并且只在第一个迭代已经完成时才开始下一个迭代


我怎么能这么做?提前谢谢你

嗯,好吧,我不能100%确定我是否正确理解了你的问题。但是,如果您尝试执行异步数组操作,等待每个项的逻辑,则可以按如下方式执行:

async loadAllUsers() {
    const test = [1,2,3,4];
    const users = [];
    for (const index in test) {
      // make some magic or transform data or something else
      await users.push(test[index])
    }

    return users;
  }

然后您可以简单地用“wait”调用这个函数。我希望这对您有所帮助。

asyncfeach
函数中,您正在解析承诺,
setTimeout
不会返回承诺。因此,如果您将
setTimeout
转换为承诺。它将按预期工作。 以下是修改后的代码:

testArray.asyncForEach(function(element) {
 return new Promise((resolve, reject) => {
  setTimeout(() => {
   console.log(element);
   return resolve(element)
 }, Math.random() * 500);
})
});
constmyarray=['a','b','c','d'];
异步函数等待(ms){//注释3
返回新承诺(resolve=>setTimeout(resolve,ms));
}
异步函数doSomething(){
等待myArray.reduce(异步(承诺,项目)=>{
等待承诺;//评论2
等待等待(1000);
//在这里,我们可以等待其他异步的东西,比如DB调用
document.getElementById('results').append(`${item}`);
},Promise.resolve());//注释1
}
设置超时(()=>doSomething(),1000)

1秒后开始
Math.random()是随机的:)使用生成器函数?@Joe Math.random()用于模拟可能需要一些时间才能完成的函数finish@LeeBrindley,我会读到的,谢谢!没问题,下面的答案也是完全可以接受的。发电机功能绝对值得一读。谢谢回答!当wait(示例中的user.push)中的函数在每次迭代中花费相同的时间时,我得到了预期的结果。但是,当该函数使用可变时间(可以用setTimeout模拟,如所提供的示例中所示)时,将返回未排序的项。我认为这是因为所有for循环迭代都是同时启动的,即使每个迭代在其自身的处理过程中也是异步的。我只需要一次运行一个迭代谢谢回答!你说得对,就这么简单。我不知道为什么我在这个问题上被耽搁了这么多时间:/谢谢你的回答和解释!现在我对reduce()的功能有了一点更好的理解,可能我没有像应该的那样使用它。当然,我会努力实现你的回应,它解决了我所有的疑问,似乎是我问题的完美解决方案!