js里async和await的用法

Administrator
Administrator
发布于 2025-03-10 / 25 阅读
0
0

js里async和await的用法

重要知识点梳理

  • 浏览器的内核采用单线程模式

  • async函数是返回Promise的函数,await用来等待Promise的结果

  • await只能在async函数中使用,不能在顶层作用域直接使用

用法详解

1.当我在一个async函数里使用await的时候,它会暂停函数的执行,等待后面的Promise解决,然后返回解决后的值。比如await somePromise,这样会等到somePromise变成fulfilled状态,然后得到它的结果。如果Promise被reject了,就会抛出异常,需要用try...catch来捕获处理。

async function getData() {
    try {
        const data = await fetchData();
        console.log(data);
    } catch (error) {
        console.error('出错:', error);
    }
}

2.async函数返回的是一个Promise,所以调用async函数的时候,可以用.then()来处理结果,或者用await在另一个async函数里等待。

async function foo() {
    return 'hello';
}
foo().then(result => console.log(result)); // 输出 'hello'

//或者在另一个async函数里:
async function bar() {
    const result = await foo();
    console.log(result); // 同样输出 'hello'
}

3.那如果async函数里面没有return语句,那么返回的Promise会以undefined解决吗?是的。

async function noReturn() { }
noReturn().then(result => console.log(result)); // 输出 undefined

4.当一个函数里需要等待两个异步函数时,优质的处理方案

//另外,如果有多个await操作,它们会按顺序执行吗?比如:
async function multipleAwaits() {
const a = await fetchA();
const b = await fetchB();
return a + b;
}

//这里,fetchB会在fetchA完成后才会执行,对吗?所以这两个是串行的。如果想并行的话,可能需要用Promise.all,比如:
async function parallelAwaits() {
const [a, b] = await Promise.all([fetchA(), fetchB()]);
return a + b;
}

//这样,fetchA和fetchB同时进行,等待两者都完成后再继续。

5.错误处理方面,如果不用try...catch,async函数返回的Promise会被reject

async function mightFail() {
    throw new Error('出错了');
}
mightFail().catch(error => console.log(error)); // 捕获错误

//或者在另一个async函数中用await的话:
async function handleError() {
    try {
        await mightFail();
    } catch (e) {
        console.log(e);
    }
}

6.如果有一个async函数内部有一个await,后面跟着一个非Promise的值,会发生什么?

async function test() {
    const value = await 42;
    console.log(value); // 输出42
}

这时候,await会把42转换为一个已解决的Promise,所以value就是42。也就是说,如果await后面的表达式不是Promise,JavaScript会自动把它包装成Promise.resolve(表达式)。

7.关于async函数的执行顺序。

console.log('开始');
async function asyncFunc() {
    console.log('async函数内部');
    await Promise.resolve();
    console.log('await之后');
}
asyncFunc();
console.log('结束');

输出顺序应该是:开始,async函数内部,结束,await之后。因为当执行到await的时候,asyncFunc会暂停,把控制权交还给调用者,后面的同步代码执行完后,再继续执行async函数中await后面的代码。

8.不过需要注意,过度使用await可能会导致性能问题,比如不必要的串行执行。比如如果有多个独立的异步操作,应该并行执行它们,而不是一个一个等待。

// 串行执行,总时间是两者之和
const a = await fetchA();
const b = await fetchB();

// 并行执行,总时间是两者中较长的
const [a, b] = await Promise.all([fetchA(), fetchB()]);

9.关于async函数的执行时机

async function test() {
    console.log(1);
    await Promise.resolve();
    console.log(2);
}
console.log(3);
test();
console.log(4);

输出顺序是3,1,4,2。因为调用test()时,执行到console.log(1),然后await将后面的代码放入微任务队列,继续执行外面的console.log(4),同步代码执行完毕后,处理微任务,执行console.log(2)。


评论