日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

“约见”面试官系列之常见面试题第三十二篇之async和await(建议收藏)

發布時間:2023/12/10 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 “约见”面试官系列之常见面试题第三十二篇之async和await(建议收藏) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、async和await

  • async和await的概念

  • 1)async 函數是 Generator 函數的語法糖,使用 關鍵字 async 來表示,在函數內部使用 await 來表示異步
    2)ES7 提出的async 函數,終于讓 JavaScript 對于異步操作有了終極解決方案
    3)async 作為一個關鍵字放到函數的前面,用于表示函數是一個異步函數,該函數的執行不會阻塞后面代碼的執行
    4)await是等待,只能放到async函數里面,在后面放一個返回promise對象的表達式
    5)async和await是為了解決大量復雜不易讀的Promise異步的問題

  • async函數的改進

  • 1)內置執行器,Generator 函數的執行必須依靠執行器,而 Aysnc 函數自帶執行器,調用方式跟普通函數的調用一樣
    2)更好的語義,async 和 await 相較于 * 和 yield 更加語義化
    3)更廣的適用性,co 模塊約定,yield 命令后面只能是 Thunk 函數或 Promise對象,而 async 函數的 await 命令后面則可以是 Promise 或者 原始類型的值(Number,string,boolean,但這時等同于同步操作)
    4)返回值是 Promise,async 函數返回值是 Promise 對象,比 Generator 函數返回的 Iterator 對象方便,可以直接使用 then() 方法進行調用
    5)async方式,流程清晰,直觀、語義明顯,操作異步流程就如同操作同步流程, async 函數自帶執行器,執行的時候無需手動加載。對于Promise的方式,如果處理流程復雜,整段代碼將會充滿then,不然很好的表示流程。對于Generator 方式,函數的執行需要依靠執行器,每次都需要通過 g.next() 的方式去執行

  • async和await的實例

  • 1)async 作為一個關鍵字放到函數的前面,用于表示函數是一個異步函數,該函數的執行不會阻塞后面代碼的執行
    實例代碼:

    async function timeout(){return "hello word";}timeout();// Promise __proto__: Promise [[PromiseStatus]]: "resolved" [[PromiseValue]]: "hello word"//async返回的是 promise 對象console.log(timeout());// 我在后面,但是我是先執行的console.log("我在后面,但是我是先執行的");

    2)async聲明的函數的返回本質上是一個Promise,async函數內部會返回一個Promise對象,then方法回調函數的參數
    實例代碼:

    // hello world11async function f1(){return "hello world11";};f1().then((v)=>console.log(v));

    3)await的本質是可以提供等同于”同步效果“的等待異步返回能力的語法糖,用await聲明的Promise異步返回,必須“等待”到有返回值的時候,代碼才繼續執行下去
    實例代碼:

    /* hello1我是hello2輸出 hello1*/const test = async()=>{let message = "hello1";let result = await message;console.log(result);console.log("我是hello2");return result;};test().then(result =>{console.log("輸出",result);});

    4)async 函數內部的實現原理是resolved,如果函數內部拋出錯誤, 則會導致返回的 Promise 對象狀態變為 reject 狀態,promise 對象有一個catch 方法進行捕獲,被 catch 方法回調函數接收到
    實例代碼:

    async function timeout2(flag){if(flag){return "hello world";}else{throw "failed";}}// 如果函數內部拋出錯誤, promise 對象有一個catch 方法進行捕獲timeout2(false).catch(err => {console.log(err);});// hello word// 調用Promise.resolve() 返回promise 對象console.log(timeout2(true));// Uncaught (in promise) failed// 調用Promise.reject() 返回promise 對象console.log(timeout2(false));

    5)async必須聲明的是一個function,await就必須是在這個async聲明的函數內部使用,必須是直系,作用域鏈不能隔代,在后面放一個返回promise對象的表達式
    實例代碼:

    // 需求:2s后讓數值乘以2function doubleAfter(num){return new Promise((resolve,reject)=>{setTimeout(()=>{resolve(2*num)},2000);});}// 60// 等待2s后,promis開始resolve,返回值async function test(){let result = await doubleAfter(30);console.log(result);}test();// 240//等待6s后,promis開始resolve,返回值async function test2(){let first = await doubleAfter(30);let second = await doubleAfter(40);let third = await doubleAfter(50);console.log(first+second+third);}test2();

    6)函數的錯誤處理,當 async 函數中只要一個 await 出現 reject 狀態,則后面的 await 都不會被執行,可以添加 try/catch
    實例代碼:

    let a;async function f5(){await Promise.reject("error");a = await 1;}//f5().then(v=>console.log(a));// try/catch 解決// Uncaught (in promise) ReferenceError: error is not definedat f6 (test13.html:124)let a3;async function f6(){try{await Promise.reject("error");}catch{console.log(error);}a3 = await 123;return a3;}f6().then((v)=>console.log(a3));
  • async/await的實戰

  • 1)需求分析:有兩個延時函數,先延時1秒,在延遲2秒,再延時1秒,最后輸出“完成”
    2)實例代碼:

    // 延時函數 const setDelay = (millisecond) => {return new Promise((resolve, reject)=>{if (typeof millisecond != 'number') reject(new Error('參數必須是number類型'));setTimeout(()=> {resolve(`我延遲了${millisecond}毫秒后輸出的`)}, millisecond)}) } const setDelaySecond = (seconds) => {return new Promise((resolve, reject)=>{if (typeof seconds != 'number' || seconds > 10) reject(new Error('參數必須是number類型,并且小于等于10'));setTimeout(()=> {resolve(`我延遲了${seconds}秒后輸出的,注意單位是秒`)}, seconds * 1000)}) }/* 我延遲了${millisecond}毫秒后輸出的我延遲了${seconds}秒后輸出的,注意單位是秒我延遲了${millisecond}毫秒后輸出的完成*/ (async ()=>{const result = await setDelay(1000);console.log(result);console.log(await setDelaySecond(2));console.log(await setDelay(1000));console.log('完成了'); })()

    二、async和await的面試題總結

  • 談談對 async/await 的理解,async/await 的實現原理是什么?
    1)async/await 就是 Generator 的語法糖,使得異步操作變得更加方便
    2)async 函數就是將 Generator 函數的星號(*)替換成 async,將 yield 替換成await
    3)async 是 Generator 的語法糖,這個糖體現在這幾個方面:
    • async函數內置執行器,函數調用之后,會自動執行,輸出最后結果,而Generator需要調用next或者配合co模塊使用
    • 更好的語義,async和await,比起星號和yield,語義更清楚了,async表示函數里有異步操作,await表示緊跟在后面的表達式需要等待結果
    • 更廣的適用性,co模塊約定,yield命令后面只能是 Thunk 函數或 Promise 對象,而async 函數的 await 命令后面,可以是 Promise 對象和原始類型的值
    • 返回值是Promise,async函數的返回值是 Promise 對象,Generator的返回值是 Iterator,Promise 對象使用起來更加方便
      4)async/await 函數的實現原理,就是將 Generator 函數和自動執行器,包裝在一個函數里
      5)實例代碼分析:
    function my_co(it) {return new Promise((resolve, reject) => {function next(data) {try {var { value, done } = it.next(data);}catch(e){return reject(e);}if (!done) { //done為true,表示迭代完成//value 不一定是 Promise,可能是一個普通值。使用 Promise.resolve 進行包裝。Promise.resolve(value).then(val => {next(val);}, reject);} else {resolve(value);}}next(); //執行一次next}); } function* test() {yield new Promise((resolve, reject) => {setTimeout(resolve, 100);});yield new Promise((resolve, reject) => {// throw Error(1);resolve(10)});yield 10;return 1000; }my_co(test()).then(data => {console.log(data); //輸出1000 }).catch((err) => {console.log('err: ', err); });
  • 使用 async/await 需要注意什么?
    1)await 命令后面的Promise對象,運行結果可能是 rejected,此時等同于 async 函數返回的 Promise 對象被reject。因此需要加上錯誤處理,可以給每個 await 后的 Promise 增加 catch 方法;也可以將 await 的代碼放在 try…catch 中
    2)多個await命令后面的異步操作,如果不存在繼發關系,最好讓它們同時觸發
    實例代碼:
  • //下面兩種寫法都可以同時觸發 //法一 async function f1() {await Promise.all([new Promise((resolve) => {setTimeout(resolve, 600);}),new Promise((resolve) => {setTimeout(resolve, 600);})]) } //法二 async function f2() {let fn1 = new Promise((resolve) => {setTimeout(resolve, 800);});let fn2 = new Promise((resolve) => {setTimeout(resolve, 800);})await fn1;await fn2; }

    3)await命令只能用在async函數之中,如果用在普通函數,會報錯
    4)async 函數可以保留運行堆棧
    實例代碼:

    / * 函數a內部運行了一個異步任務b()。當b()運行的時候,函數a()不會中斷,而是繼續執行。 * 等到b()運行結束,可能a()早就* 運行結束了,b()所在的上下文環境已經消失了。 * 如果b()或c()報錯,錯誤堆棧將不包括a()。 */ function b() {return new Promise((resolve, reject) => {setTimeout(resolve, 200)}); } function c() {throw Error(10); } const a = () => {b().then(() => c()); }; a(); /** * 改成async函數 */ const m = async () => {await b();c(); }; m();

    ?

    • 本面試題為前端常考面試題,后續有機會繼續完善。我是歌謠,一個沉迷于故事的講述者。

      歡迎一起私信交流。

      “睡服“面試官系列之各系列目錄匯總(建議學習收藏)?

    總結

    以上是生活随笔為你收集整理的“约见”面试官系列之常见面试题第三十二篇之async和await(建议收藏)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。