编写承诺的异步/等待版本

时间:2019-01-15 20:09:27

标签: javascript async-await

下面的代码按预期每秒记录一次“ hello world”。

function moveOneStep() {
  return new Promise((res, rej) => {
    setTimeout(() => {
      res(console.log('Hello world!'))
    }, 1000)
  })  
}

async function main() {
  await moveOneStep();
  await moveOneStep();
  await moveOneStep();
  await moveOneStep();
}

考虑到return函数的async值与promise中resolve函数返回的值相对应,为什么下面的代码不能输出相同的结果,而是记录所有结果“ hello world”一下:

async function moveOneStepAsync() {
  setTimeout(() => {
    return console.log('Hello world!');
  }, 1000);
}

async function main() {
  await moveOneStepAsync();
  await moveOneStepAsync();
  await moveOneStepAsync();
  await moveOneStepAsync();
}

2 个答案:

答案 0 :(得分:6)

这是因为setTimeout在您的await函数中未将承诺返回给main。 setTimeout本身将同步执行。它将回调添加到事件循环中,该回调作为参数传递以在提到的时间执行。

在此代码中,回调的返回也没有任何意义,因为回调将在1秒钟内运行,并且返回的值将无处获取。

async关键字告诉您该函数返回promise并且其中可能包含await个代码。因此,由于您的代码中没有等待,所以看起来像

function moveOneStepAsync() {
  setTimeout(() => {
    return console.log('Hello world!');
  }, 1000);
  return Promise.resolve();
}

因此您的await主用户将等待一个事件循环滴答声,进入下一个“步骤”

阅读有关setTimeout,事件循环以及期待更深入了解的内容

答案 1 :(得分:1)

您不会对该函数进行任何return的操作,而是返回内部setTimeout函数,并且对该值不执行任何操作。调用setTimeout不会返回承诺,而是立即返回计时器。因此,所有moveOneStepAsync调用都会立即执行,计时器会被设置,并在一秒钟后触发。