async和await的使用和执行步骤理解

133 阅读5分钟

async函数

async 函数是使用async关键字声明的函数。asyncawait关键字让我们可以用一种更简洁的方式写出基于Promise的异步行为,而无需刻意地链式调用promise。
语法
async function name([param[, param[, ... param]]]) {
    statements 
}
name:函数名称
param:参数名称
statements:函数体
返回值:一个promise
基本demo

描述 async 函数可能包含 0 个或者多个await表达式。await 表达式会暂停整个 async 函数的执行进程并出让其控制权,只有当其等待的基于 promise 的异步操作被兑现或被拒绝之后才会恢复进程。promise 的解决值会被当作该 await 表达式的返回值。使用async / await关键字就可以在异步代码中使用普通的try / catch代码块。

function api(interval) {
    return new Promise((resolve,reject)=>{
        setTimeout(() => {
            resolve(1)
        }, interval);
    })
}
async function useApi() {
    console.log(1)
    await api(3000)
    console.log(2)
}
let result = useApi()
console.log(result)

//输出结果
1
Promise[[PromiseState]]: "fulfilled"[[PromiseResult]]: undefined
2
//输出结果分析
useApi()执行 async函数马上执行输出1 遇到await会让出控制权,await下方的代码会放到eventqueue的微任务中,接着输出result 3s后api返回成功在到微任务中寻找任务,输出2

与普通函数不同的是要用async修饰符修饰,会返回一个promise

demo2 async 函数的返回值看起来不是 promise
async function foo() {
   await 1
}
//等价于
function foo() {
   return Promise.resolve(1).then(() => undefined)
}
mdn官方案例理解

var resolveAfter2Seconds = function () {
    console.log("starting slow promise");
    return new Promise(resolve => {
        setTimeout(function () {
            resolve("slow");
            console.log("slow promise is done");
        }, 2000);
    });
};

var resolveAfter1Second = function () {
    console.log("starting fast promise");
    return new Promise(resolve => {
        setTimeout(function () {
            resolve("fast");
            console.log("fast promise is done");
        }, 1000);
    });
};

var sequentialStart = async function () {
    console.log('==SEQUENTIAL START==');
    const slow = await resolveAfter2Seconds();
    console.log(slow); 
    const fast = await resolveAfter1Second();
    console.log(fast); 
}

var concurrentStart = async function () {
    console.log('==CONCURRENT START with await==');
    const slow = resolveAfter2Seconds(); // starts timer immediately
    const fast = resolveAfter1Second(); // starts timer immediately
}

var concurrentPromise = function () {
    console.log('==CONCURRENT START with Promise.all==');
    return Promise.all([resolveAfter2Seconds(), resolveAfter1Second()]).then((messages) => {
        console.log(messages[0]); // slow
        console.log(messages[1]); // fast
    });
}

var parallel = async function () {
    console.log('==PARALLEL with await Promise.all==');
    await Promise.all([
        (async () => console.log(await resolveAfter2Seconds()))(),
        (async () => console.log(await resolveAfter1Second()))()
    ]);
}


var parallelPromise = function () {
    console.log('==PARALLEL with Promise.then==');
    resolveAfter2Seconds().then((message) => console.log(message));
    resolveAfter1Second().then((message) => console.log(message));
}

 sequentialStart();
 
 分析
    输出  ==SEQUENTIAL START==
    执行resolveAfter2Seconds函数 
        输出 starting slow promise"
        在事件队列里创建宏任务
        遇到await    console.log(slow);const fast = await resolveAfter1Second();console.log(fast); //在事件队列里创建一个微任务(要await返回成功后才执行)
        2sresolve("slow"); 将promise改为成功态 输出 slow promise is done
        主线程空闲后去异步微任务去找可执行的任务 发现状态为resolve 立马执行 输出 slow
        resolveAfter1Second() 函数执行 输出starting fast promise 在事件队列里创建宏任务 遇到await console.log(fast); //在事件队列里创建一个微任务(要await返回成功后才执行)
        1sresolve("fast"); 将promise改为成功态 输出 fast promise is done
        主线程空闲后去异步微任务去找可执行的任务 发现状态为resolve 立马执行 输出 fast
        输出结果为 
            ==SEQUENTIAL START== 
            starting slow promise" 
            2s(后) slow promise is done
            slow 
            starting fast promise
            1s(后) fast promise is done
            fast


setTimeout(concurrentStart, 4000); 

分析
    concurrentStart()函数执行 输出 ==CONCURRENT START with await==
    resolveAfter2Seconds()函数执行 输出 starting slow promise 在事件队列中创建一个宏任务一
    resolveAfter1Second()函数执行 输出 starting fast promise 在事件队列中创建一个宏任务二
    console.log(await slow);执行 console.log(await fast)被放在微任务中
    同步代码执行完毕 主线程空闲 去事件队列里寻找微任务发现微任务没达到执行条件  开始执行宏任务
    1s后宏任务二执行完毕 输出fast promise is done" 并将fast promise改为成功状态
    1s后宏任务一执行完毕 输出slow promise is done" 并将slow promise改为成功状态输出slow
    主线程短暂空闲 去事件队列里寻找微任务发现微任务达到执行条件fast
    输出结果为 
        ==CONCURRENT START with await==
        starting slow promise
        starting fast promise
        (1s后) fast promise is done
        (1s后) slow promise is done
        slow
        fast

setTimeout(concurrentPromise, 7000);

分析
    concurrentPromise()函数执行 输出==CONCURRENT START with Promise.all==
    resolveAfter2Seconds()函数执行 输出 starting slow promise 在事件队列中创建一个宏任务一
    resolveAfter1Second()函数执行 输出 starting fast promise 在事件队列中创建一个宏任务二
    1s后宏任务二执行完毕 输出fast promise is done" 并将fast promise改为成功状态
    1s后宏任务一执行完毕 输出slow promise is done" 并将slow promise改为成功状态
    任务一和宏任务二都执行完毕 输出 slow fast
    输出结果为 
        ==CONCURRENT START with Promise.all==
        starting slow promise
        starting fast promise
        (1s后) fast promise is done
        (1s后) slow promise is done
        slow
        fast

setTimeout(parallel, 10000);

分析
    parallel()函数执行 输出==PARALLEL with await Promise.all==
    (async () => console.log(await resolveAfter2Seconds()))() 执行输出 starting slow promise 在事件队列中创建一个宏任务一
    (async () => console.log(await resolveAfter1Second()))() 输出 starting fast promise 在事件队列中创建一个宏任务二
    1s后宏任务二执行完毕 输出fast promise is done" 并将fast promise改为成功状态 输出fast
    1s后宏任务一执行完毕 输出slow promise is done" 并将slow promise改为成功状态 输出 slow
    输出结果为 
        ==PARALLEL with await Promise.all==
        starting slow promise
        starting fast promise
        fast promise is done
        fast
        slow promise is done
        slow

setTimeout(parallelPromise, 13000);

分析
    parallelPromise()函数执行 输出==PARALLEL with Promise.then==
    resolveAfter2Seconds().then((message) => console.log(message)); 执行输出 starting slow promise 在事件队列中创建一个宏任务一
    resolveAfter1Seconds().then((message) => console.log(message)); 输出 starting fast promise 在事件队列中创建一个宏任务二
    1s后宏任务二执行完毕 输出fast promise is done" 并将fast promise改为成功状态
    1s后宏任务一执行完毕 输出slow promise is done" 并将slow promise改为成功状态
    输出结果为 
        ==PARALLEL with await Promise.all==
        starting slow promise
        starting fast promise
        fast promise is done
        fast
        slow promise is done
        slow