首页 > 解决方案 > 像我 5 岁一样解释我 - ES6 Promises & async/await 差异,我的代码“正确”吗?

问题描述

我很难理解 ES6 Promises 和 Async/await。

我在 youtube 上查找了解释这些主题的视频,但我仍然无法沉思它们之间有什么区别,什么时候应该使用 Promises over Async/await 或 Async/await over Promises?

另外我什么时候知道我的代码是“有效”的承诺还是异步/等待。

在这里,我有两个示例(两个都有效),它们从我的本地 JSON 服务器获取“公司”,当它完成时,它会遍历这些公司。

第一个例子:(使用承诺)

function getCompanies() {
    return new Promise((resolve, reject) => {
        fetch(`http://localhost:3000/companies`)
        .then(response => response.json())
        .then(response => resolve(response))
        .catch(error => reject(error))
    })
}

function loopCompanies(companies) {
    companies.forEach((company) => {
        console.log(company);
    })
}

getCompanies().then(response => loopCompanies(response)).catch(error => console.log(error));

第二个例子:(使用异步/等待)

async function getCompanies() {
    let response = await fetch(`http://localhost:3000/companies`);

    let processedResponse = await response.json();

    return processedResponse
}

function loopCompanies(companies) {
    companies.forEach((company) => {
        console.log(company);
    })
}

async function doIt() {
    try{
        let response = await getCompanies();
        loopCompanies(response)
    } catch(error) {
        console.log(error)
    }
}
doIt()

所以我不知道我是否应该在示例 1 中使用 Promises?

这就是我应该在示例 2 中使用 Async/await 的方式吗?

它们之间有什么区别

标签: javascriptasynchronouspromiseasync-await

解决方案


第一个示例是不必要地将手动创建的 Promise 包装在您已经拥有的 Promise 周围。由于各种原因,这是一种反模式。你应该只返回已经返回的承诺fetch()。你可以这样做:

function getCompanies() {
    return fetch(`http://localhost:3000/companies`)
        .then(response => response.json());
    })
}

function loopCompanies(companies) {
    companies.forEach((company) => {
        console.log(company);
    })
}

getCompanies().then(response => loopCompanies(response)).catch(error => console.log(error));

第二个例子(使用async/await)对我来说看起来不错。您可以通过更改它来简化它:

async function getCompanies() {
    let response = await fetch(`http://localhost:3000/companies`);
    let processedResponse = await response.json();
    return processedResponse
}

对此:

async function getCompanies() {
    let response = await fetch(`http://localhost:3000/companies`);
    return response.json();
}

因为不需要await一个值,你只是要去return。相反,您可以直接返回承诺。要么生成相同的结果,但第二种方法使用更少的代码。


我在 youtube 上查找了解释这些主题的视频,但我仍然无法沉思它们之间有什么区别,什么时候应该使用 Promises over Async/await 或 Async/await over Promises?

asyncawait绝对使用承诺。事实上,除非你做出承诺,await否则没有任何用处。await而且,async函数总是返回一个承诺。所以,async/await不是承诺的替代品。它们是一种替代方法.then(),可为您提供不同的语法,有时对编写、调试和阅读更友好,尤其是当您想要对多个异步操作进行排序时。

另外我什么时候知道我的代码是“有效”的承诺还是异步/等待。

当您的代码在成功和错误条件下都提供正确的结果并且编写时没有不必要的步骤和反模式时,您的代码是有效的。除此之外,没有什么神奇的答案。据我所知,没有任何工具可以告诉你这一点。就像没有工具可以告诉你 100 行函数是否写得好。您必须学习 Javascript 异步开发的良好编码实践,然后才能识别出好的模式和不太好的模式。

所以我不知道我是否应该在示例 1 中使用 Promises?

有关从示例 1 中删除反模式的信息,请参见我上面的固定示例。

这就是我应该在示例 2 中使用 Async/await 的方式吗?

是的,这很好,但可以进一步简化,如我在上面的示例中所示。

它们之间有什么区别

在我的两个修改示例中,它们实现了相同的结果。它们只是两种不同的编码风格。你可以决定你喜欢哪一个。两者都不比另一个“更正确”。

我的个人风格是async/await在有充分理由使用它时使用,例如:

  1. 我正在排序的多个异步操作。
  2. 当它导致更简单,万无一失的错误处理时。
  3. 当它导致看起来更简单的代码时。
  4. 当我想确保同步异常被捕获并变成被拒绝的承诺时。
  5. 当我不需要在async/await没有转译的情况下可能不支持的旧 JS 引擎中运行时。

推荐阅读