JavaScript中的Async/await

JavaScript中的Async/await

在本文中,我们将解释JavaScript中的async/await。

YouTube Video

JavaScript中的Async/await

JavaScript中的async(以及await)是为了使编写异步操作更直观且更易读而设计的功能。通过使用这个,您可以减少传统回调函数和Promise链的复杂性,并且以类似同步代码的方式编写异步代码。

async函数

async用于将函数定义为异步函数。async函数总是返回一个Promise。在标记为async的函数中,可以使用await等待Promise的结果返回。

async函数的基本语法

1async function myAsyncFunction() {
2    // Write asynchronous processing here
3    return 'Result';  // Return a Promise
4}

在这种情况下,调用myAsyncFunction()会自动返回一个Promise对象。当Promise被解析时,其结果将成为return返回的值。

示例:基本的async函数

1async function greet() {
2    return 'Hello, World!';
3}
4
5greet().then((message) => {
6    console.log(message);  // Displays "Hello, World!"
7});

await

await用于等待Promise的解析。通过使用await,您可以暂停执行直到Promise被解析,并接收Promise的结果。await只能在async函数内部使用。

示例:如何使用await

 1async function fetchData() {
 2    // Wait for the result of the Promise
 3    const data = await fetch('https://codesparklab.com/json/example.json');
 4    // Wait for the asynchronous operation to complete
 5    const jsonData = await data.json();
 6    // Retrieve and display the data
 7    console.log(jsonData);
 8}
 9
10fetchData();

在上述示例中,通过await等待fetch函数返回的Promise,然后使用其结果执行进一步的异步操作。

使用async/await进行错误处理

如果在async函数中发生错误,该错误会被视为Promise的reject处理。您可以使用try...catch语句进行错误处理。

示例:错误处理

 1async function fetchData() {
 2    try {
 3        // Invalid URL
 4        const data = await fetch('https://invalid.codesparklab.com/');
 5        const jsonData = await data.json();
 6        console.log(jsonData);
 7    } catch (error) {
 8        // Catch the error
 9        console.error('Failed to fetch data:', error);
10    }
11}
12
13fetchData();

使用try...catch块可以捕获异步操作中发生的错误,从而防止程序因错误而崩溃。

async/await的优点

与传统的Promise链相比,async/await具有以下优点:。

  • 可读性提升
    • 异步处理可以像同步代码那样编写,避免了深层嵌套的Promise链和回调的复杂性。
  • 更容易调试
    • 由于其类似于同步代码,调试和错误处理变得更容易。
  • 更好的可维护性
    • 异步流程可以更加简单地编写,便于更改或修改代码,提高长期可维护性。

示例:Promise链与async/await的对比

让我们比较一下使用Promise链和使用async/await的代码。

 1// Code using Promise chains
 2function fetchDataPromise() {
 3    fetch('https://codesparklab.com/json/example.json')
 4        .then((response) => response.json())
 5        .then((data) => {
 6            console.log(data);
 7        })
 8    .catch((error) => {
 9        console.error('Failed to fetch data:', error);
10    });
11}
12
13// Code using async/await
14async function fetchDataAsync() {
15    try {
16        const response = await fetch('https://codesparklab.com/json/example.json');
17        const data = await response.json();
18        console.log(data);
19    } catch (error) {
20        console.error('Failed to fetch data:', error);
21    }
22}

正如您所见,使用async/await可以以线性的方式编写异步流程,从而使代码更具可读性。

同时执行多个异步操作

结合Promise.all()Promise.race()await,可以同时执行多个异步操作并集中处理它们的结果。

Promise.all()

 1async function fetchMultipleData() {
 2    try {
 3        const [data1, data2] = await Promise.all([
 4            fetch('https://codesparklab.com/json/example1.json'),
 5            fetch('https://codesparklab.com/json/example2.json')
 6        ]);
 7        const jsonData1 = await data1.json();
 8        const jsonData2 = await data2.json();
 9        console.log(jsonData1);
10        console.log(jsonData2);
11    } catch (error) {
12        console.error('Failed to fetch data:', error);
13    }
14}
15
16fetchMultipleData();
  • Promise.all()可以同时解析多个Promise,并将结果作为数组返回。它会等待所有的Promise解析完成,如果其中任何一个失败,则整体会被视为失败。

Promise.race()

 1async function fetchFastestData() {
 2    try {
 3        const fastestResponse = await Promise.race([
 4            fetch('https://codesparklab.com/json/example1.json'),
 5            fetch('https://codesparklab.com/json/example2.json')
 6        ]);
 7        const jsonData = await fastestResponse.json();
 8        console.log('Fastest data:', jsonData);
 9    } catch (error) {
10        console.error('Fetch error:', error);
11    }
12}
13
14fetchFastestData();
  • Promise.race() 返回第一个被兑现或被拒绝的 Promise 的结果。当你想响应第一个完成的异步操作时,这非常有用。但是,如果第一个 Promise 失败,错误会立刻被 catch 捕获。

Promise.allSettled()

 1async function fetchWithAllSettled() {
 2    const results = await Promise.allSettled([
 3        // This URL will success
 4        fetch('https://codesparklab.com/json/example1.json'),
 5        // This URL will fail
 6        fetch('https://invalid.codesparklab.com/')
 7    ]);
 8
 9    results.forEach((result, index) => {
10        if (result.status === 'fulfilled') {
11            const url = result.value.url;
12            console.log(`Request ${index + 1} succeeded:`, url);
13        } else {
14            const reason = result.reason;
15            console.warn(`Request ${index + 1} failed:`, reason);
16        }
17    });
18}
19
20fetchWithAllSettled();
  • Promise.allSettled() 会等待所有结果,不论成功还是失败。每个结果都会以 { status, value }{ status, reason } 的形式返回,让你能够判断哪些 Promise 成功了,哪些失败了。

Promise.any()

 1async function fetchAnySuccessful() {
 2    try {
 3        const firstSuccessful = await Promise.any([
 4            // This URL will fail
 5            fetch('https://invalid.codesparklab.com/'),
 6            // This URL will success
 7            fetch('https://codesparklab.com/json/example1.json')
 8        ]);
 9        const jsonData = await firstSuccessful.json();
10        console.log('First successful response:', jsonData);
11    } catch (error) {
12        console.error('All fetch requests failed:', error);
13    }
14}
15
16fetchAnySuccessful();
  • Promise.any() 只会返回第一个成功兑现的 Promise 的结果。只有当所有 Promise 都失败时,才会抛出异常。它可以像重试机制那样使用,适用于某些 API 不稳定、直到其中一个成功为止的场景。

总结

  • async函数:始终返回一个Promise,用于编写异步处理代码。
  • await:用于等待Promise解析并获取其结果。
  • 错误处理:使用try...catch来处理异步处理中的错误。
  • 多个异步操作:通过使用 Promise.all() 等方法,你可以同时运行多个异步任务。

async/await是处理异步操作的强大工具,请务必利用它们来简化复杂的异步逻辑。

您可以在我们的YouTube频道上使用Visual Studio Code跟随上述文章进行学习。 请也查看我们的YouTube频道。

YouTube Video