Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/375.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 foreach循环中具有回调的函数_Javascript_Foreach_Es6 Promise - Fatal编程技术网

Javascript foreach循环中具有回调的函数

Javascript foreach循环中具有回调的函数,javascript,foreach,es6-promise,Javascript,Foreach,Es6 Promise,我试图在forEach循环中使用回调函数 在进入下一步之前,我需要等待执行完成 这是我的密码: const arr = '6,7,7,8,8,5,3,5,1' const id = arr.split(','); const length = id.length; id.forEach( (x, index) => { (function FnWithCallback () { setTimeout(() => { console.log(x) }, 5000);

我试图在
forEach
循环中使用回调函数

在进入下一步之前,我需要等待执行完成

这是我的密码:

const arr = '6,7,7,8,8,5,3,5,1'

const id = arr.split(',');

const length = id.length;


id.forEach( (x, index) => {
  (function FnWithCallback () {
    setTimeout(() => { console.log(x) }, 5000);
  })();
});

console.log('done');
我想出了一个窍门:

const arr = '6,7,7,8,8,5,3,5,1'

const id = arr.split(',');

const length = id.length;

const fn = () => {
  return new Promise (resolve => {
    id.forEach( (id, index) => {
      setTimeout(() => {console.log(id)}, 3000);

      if(index === (length - 1))
         resolve();
    })
  })
}

fn().then(()=> {
  console.log('done');
})
但是黑客似乎被破解了

我能有一个真正的解决办法吗? NPM包将非常有用

注意:我看过async.js。我不确定这是否是我想要的,因为我正试图避免回调地狱。

解决方案是提示回调函数,然后结合使用:

const arr='6,7,8,8,5,3,5,1'
函数FnWithCallback(id,cb){
设置超时(cb,1000,id)
}
const promisified=id=>新承诺(解析=>{
FnWithCallback(id,解析)
})
const promises=arr.split(',').map(promisified)
承诺。所有(承诺)。然后(id=>{
控制台日志(id)
console.log('Done')

})
如果要确保异步操作不是并行运行,而是一个接一个地运行,请继续阅读。如果您希望按顺序获得结果,但不关心它们是否并行运行,请参阅

您可以使用
async
函数在
for
循环中
等待
承诺,因为指定的计时器非常有用:

const timer = ms => new Promise(res => setTimeout(res, ms));

(async function() {
  for(const id of ["6", "7", "7" /*...*/]) {
     await timer(5000);
     console.log(id);
  }
  console.log("done");
})();
这也可以通过使用回调链来实现,但是我不确定这是否可以理解/有用(只是想表明回调不必来自地狱):


您可以使用从初始解析的承诺开始链接承诺。你必须将你的回访变成承诺,这样你才能将它们链接起来:

const arr='6,7,8,8,5,3,5,1'
常量id=arr.split(',');
常量长度=ids.length;
常量超时=(fn,ms)=>新承诺(res=>{
setTimeout(()=>{fn();res();},毫秒);
});
id.reduce((以前的承诺,id)=>{
返回以前的承诺。然后(()=>{
返回超时(()=>console.log(id),200);
});
},Promise.resolve());

console.log('done')
您可以尝试这种方法,其中,
promisefy
将接收任何类型的值作为以后要解析的参数

const IDs = '6,7,7,8,8,5,3,5,1'.split(',');

// simulates an async response after 1s
const promisefy = (value) => new Promise((resolve) => {
  setTimeout(() => {
    resolve(value);
  }, 1000);
});

// stores all async responses
const responses = IDs.map((id, index) => {
  return promisefy(id);
});

// executes sequentially all responses
responses.forEach((resp, index) => {
  resp.then((value) => console.log(`id: ${value}, index: ${index}`));
});
或使用


你好!为我的困惑道歉,但你想实现什么?是否只想打印出
id
的每个索引?
id
是否被未显示的其他代码修改?我不明白为什么这需要异步完成。@broAhmed实际上,回调函数正在DB中插入值。@Jonaswillms按顺序等待。您正在寻找的npm包是。或者只是去做承诺,这会在
wait
内部循环中引起一些警告,因为它会通过将每个调用延迟到前一次完成而不是并行启动来降低吞吐量。@patrick我问OP,回答是“按顺序等待”,这似乎是他们想要的。他们可能会对“按顺序获得结果”和“按时间顺序确定结果”之间的区别感到困惑
const IDs = '6,7,7,8,8,5,3,5,1'.split(',');

// simulates an async response after 1s
const promisefy = (value) => new Promise((resolve) => {
  setTimeout(() => {
    resolve(value);
  }, 1000);
});

// stores all async responses
const responses = IDs.map((id, index) => {
  return promisefy(id);
});

// executes sequentially all responses
responses.forEach((resp, index) => {
  resp.then((value) => console.log(`id: ${value}, index: ${index}`));
});
// stores all async responses
const responses2 = IDs.map((id) => promisefy(id));

// executes sequentially all responses
responses2
  .reduce((_, resp, index) => {
      return resp.then((value) => console.log(`id: ${value}, index: ${index}`));
    }, null)
  .then(() => console.log('done'));