在每个循环之前完成ForEach完成

时间:2018-04-23 11:02:27

标签: javascript promise

这段代码等待2s然后立即调试console.log的每个元素。如何更改此forEach以等待每个超时完成后再循环到下一个?所以我想要的是2s,然后它记录“1”,然后另外2s经过,然后它记录“2”等我看了承诺(这里实现了一半)但我不明白它是如何工作的

MyArray = [1, 2, 3];

MyArray.forEach(async element => {
    await setTimeout(() => {
        console.log(element);
    }, 2000);
});

4 个答案:

答案 0 :(得分:2)

Async不能与setTimeout一起使用,您可以返回稍后解析的协议以及解析后返回下一个值的承诺,依此类推。 Reduce可以为您做到这一点:

const MyArray = [1, 2, 3];
const later = (howLong, element) =>
  new Promise(
    resolve =>
      setTimeout(() => {
        console.log(element);
        resolve(element)
      }, howLong)
  );

MyArray.reduce(
  (all, element) =>
    all.then(
      () => later(2000, element)
    ),
  Promise.resolve()
).then(()=>console.log("done"));

以下是平行的:

const MyArray = [1, 2, 3];

Promise.all(
  MyArray.map(element =>
    new Promise(
      resolve=>
        setTimeout(() => {
          console.log(element);
          resolve(element)
        }, 2000)
    )
  )
).then(
  results=>console.log("results",results)
)

答案 1 :(得分:1)

您希望系列地运行承诺,其中每个承诺将在2秒后解决,然后下一个承诺将运行

MyArray.reduce(function(chain, element) {
  return chain.then(function() {
    return new Promise(function(resolve, reject) {
     setTimeout(() => {
       console.log(element);
       resolve(element)
     }, 2000);
    });
  })
}, Promise.resolve([]))

答案 2 :(得分:1)

您也可以使用简单的递归异步音序器,如下所示;

var sequenceAsync = ([d,...ds]) => d !== void 0 && asyncTask(d).then(v => (console.log(v), sequenceAsync(ds))),
    asyncTask     = n => new Promise(v => setTimeout(v, 1000, n)),
    datas         = [1,2,3];

sequenceAsync(datas);

void 0是检查undefined的完美undefined值。

答案 3 :(得分:0)

试试这个

function resolveAfter2Seconds(i) {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(i);
    }, 2000);
  });
}

async function asyncCall(MyArray) {
  for(var i=0; i<MyArray.length; i++){
  var result = await resolveAfter2Seconds(MyArray[i]);
  console.log(result);
  }
  
 
}
var MyArray = [1, 2, 3];
asyncCall(MyArray);

相关问题