使用setTimeout()在JavaScript中异步等待的工作方式

时间:2018-11-14 11:09:54

标签: javascript

为什么此代码不起作用

我想以简单的方式学习同步

const post = [];

function getPost(post) {
     console.log(post)
 }

async function createPost (post) {
  await setTimeout(() => {
    post.push({
      name: "John", work: "Developer"
    })
  }, 1000)
  getPost(post);
}

createPost(post);

1 个答案:

答案 0 :(得分:10)

这不起作用,因为setTimeout没有返回承诺。如果您await是一个非承诺者,您将立即获得值(几乎¹)。您还希望使用createPost返回的promise,您的代码当前并未执行该操作。

您必须为setTimeout做一个包装,以返回一个承诺,例如as shown in my answer here,尽管这些天我会做一些修改:

function timeout(delay, ...args) {
    return new Promise(function(resolve) {
        setTimeout(resolve, delay, ...args);
    });
}

这是适用于您的代码的,尽管我认为您代码中的setTimeout实际上是其他异步操作(ajax,MongoDB等)的替代品,并且我不会构建代码这样(我将由post创建并返回createPost,而不是createPost结束的数组)

function timeout(delay, ...args) {
    return new Promise(function(resolve) {
        setTimeout(resolve, delay, args);
    });
}

const post = [];

function getPost(post) {
    console.log(post)
}

async function createPost(post) {
  await timeout(1000);
  post.push({
      name: "John", work: "Developer"
  });
  getPost(post);
}

// Going async at top level
(async () => {
    await createPost(post);
})().catch(error => {
    console.error(error);
});


¹“几乎立即” a = await b; ...Promise.resolve(b).then(a => ...)的语法糖(实际上是非常好的糖)(加上错误处理)。如果b不是承诺,则a的分配会在执行await的任务之后的微任务处理中发生。有关my answer here中的任务和微任务的更多信息。 / p>