ZetCode

JS async/await

最后修改于 2023 年 10 月 18 日

在本文中,我们将展示如何使用 async 和 await 关键字进行异步编程。

JavaScript 是一种异步编程语言。它使用 Promise 来处理异步操作。在引入 Promise 之前,异步操作由回调函数处理。

一个 Promise 是一个尚未完成的异步任务的占位符。(在某些编程语言中,Promise 称为 future。) asyncawait 关键字使基于 Promise 的异步行为能够以更简洁的风格编写。

使用 async 关键字,我们定义一个异步函数。每个 async 函数都返回一个 Promise。Async 函数可以包含零个或多个 await 表达式。await 关键字会暂停函数的执行,直到返回的 Promise 被履行或拒绝。

await 关键字仅在常规 JavaScript 代码中的 async 函数内有效。

注意: Async 函数总是返回一个 Promise。如果 async 函数的返回值不是显式地一个 Promise,它会被自动包装在一个 Promise 中。

JS async/await 简单示例

以下是一个使用 async/await 关键字的简单异步 JS 代码。

main.js
const work = () => {
    return new Promise(resolve => {
        setTimeout(() => resolve('doing work'), 3000);
    })
}

const doWork = async () => {
    console.log(await work());
}

console.log('before');
doWork();
console.log('after');

在这个例子中,我们有一个异步函数。

const work = () => {
    return new Promise(resolve => {
        setTimeout(() => resolve('doing work'), 3000);
    })
}

work 函数是一个虚拟函数,代表一个持续三秒的任务。

const doWork = async () => {
    console.log(await work());
}

doWork 是一个 async 函数,它调用 work。使用 await,它会暂停执行,直到 work 函数被解决。

doWork();

doWork 函数被调用。

$ node simple.js 
before
after
doing work

请注意,'doing work' 消息是在 console.log 语句之后打印的。因此,本质上,doWork 函数不会阻塞 main.js 文件中的语句。


在引入 async/await 关键字之前,使用了回调函数。

main.js
const work = () => {
    return new Promise(resolve => {
        setTimeout(() => resolve('doing work'), 3000);
    })
}

console.log('before');

work().then(e => {
    console.log(e);
    console.log('finished');
});

console.log('after');

这是一个使用回调函数的相同示例。使用回调函数创建更复杂的异步代码比较困难。

JS async/await 与 fetch

fetch 是一个全局函数,它接受 url 和 options 参数,并返回一个 promise。该 promise 解决为请求的响应。

let promise = fetch(url, [options])

如果没有提供选项,则会生成一个简单的 GET 请求,用于下载 url 的内容。

<script>
    async function doRequest() {
        let url = 'http://webcode.me';
        let res = await fetch(url);

        if (res.ok) {

            let text = await res.text();

            return text;
        } else {
            return `HTTP error: ${res.status}`;
        }
    }

    doRequest().then(data => {
        console.log(data);
    });

</script>

在浏览器中的 JS 代码中使用 fetch 生成一个异步 GET 请求。

JS async 截图

在下一个示例中,我们创建一个网页的截图。我们使用 Puppeteer 库。

$ npm i puppeteer

我们使用 npm i puppeteer 命令安装 Puppeteer。

main.js
const puppeteer = require('puppeteer');

(async () => {

  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('http://webcode.me');
  await page.screenshot({ path: 'webcode.png' });

  await browser.close();
})();

在匿名函数内部,我们执行几个异步操作。每个操作都使用 await 等待。

来源

JS async 函数

在本文中,我们使用 async 和 await 关键字创建了异步 JS 程序。

作者

我叫 Jan Bodnar,是一位对编程充满热情的程序员,拥有丰富的编程经验。自 2007 年以来,我一直在撰写编程文章。迄今为止,我撰写了超过 1,400 篇文章和 8 本电子书。我拥有超过十年的编程教学经验。

查看 所有 JavaScript 教程。