中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

async-await消滅異步回調的方法

發布時間:2022-07-26 17:52:21 來源:億速云 閱讀:121 作者:iii 欄目:開發技術

今天小編給大家分享一下async-await消滅異步回調的方法的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

    一、走進Async-await原理

    1、原理1

    async函數返回一個 Promise 對象,可以使用then方法添加回調函數。舉例說明:

    // async返回的是Promise對象?
    async function testAsync() {
        return 'hello';//上篇文章Promise對象的返回值如果不是Promise,會通過Promise.resolve()轉化為Promise,再進行處理
    }
    const result = testAsync()
    console.log(result);//Promise { 'hello' }  說明async返回的是Promise對象

    那既然async返回的是Promise對象,那么async后面的函數可以接.then()或者.catch()...嘛?我們試一試就知道了。

    // async返回的是Promise對象,并且可以接Promise的方法?
    async function testAsync() {
        // await await等待還是promise對象
        return 'hello'
    }
    testAsync()
        .then((result)=>{
            console.log(result);
        })
        .catch((error)=>{
            console.log(error);
        })
    //hello  媽耶!打印了!說明async返回的是Promise對象,并且可以接Promise的方法,并且!!!默認狀態是resolved的

    上面代碼說明,async函數內部return語句返回的值,會成為then方法回調函數的參數

    2、原理2

    當async函數內部拋出錯誤的時候,會導致返回的 Promise 對象變為reject狀態。拋出的錯誤對象會被.then()方法的第二個回調函數接收或者.catch()方法回調函數接收到。

    // async函數內部拋出錯誤或者Promise狀態為reject
    async function testError(){
        //throw new Error('出錯啦~~');
        await Promise.reject('出錯了');//await前面有return和沒有return效果一樣
    } 
    testError()
        // .then(()=>{},(error)=>{console.log(error);})
        .catch(error=>{console.log(error);})
    //Error: 出錯啦~~

    3、原理3

    await命令后面是一個 Promise 對象,返回該對象的結果。如果不是 Promise 對象,就直接返回對應的值。代碼說明:

    // await
    async function getName(){
        // return '來自星星的你';
        return await '來自星星的你';//上面直接return等價于這個return
    }
    getName()
        .then(result=>{console.log(result);})
    //來自星星的你

    4、原理4

    await的使用,必須要有async。這便是async-await的浪漫所在了:async返回的是一個Promise對象,await等待的就是這個Promise對象,所以await不能沒有async(但是async可以沒有await)。有沒有被浪漫到?反正我是醉了。如果await沒有async會怎么樣?報錯:

    // await沒有async會報錯
    function testAwait(){
        return await '西紅柿炒辣椒'
    }
    testAwait()
        .catch(error=>{
            console.log(error);
        })
    //SyntaxError: await is only valid in async function

    二、深入Async-await規則

    1、async封裝Promise

    // async封裝Promise
    async function fn1() {
        return '喜羊羊與灰太狼';// //相當于return Promise.resolve('喜羊羊與灰太狼')
        const data = await fn1();//接收data值
    }
    fn1()//執行async函數,返回的是一個Promise對象
        .then(data => {
            console.log('content =', data)
        })
    
    //content = 喜羊羊與灰太狼

    2、await相當于then

    // await---.then()
    async function getName(){
        const operate=Promise.resolve('白雪公主')//執行函數
        const name= await operate //await相當于Promise的then  operate.then(name=>{})
        console.log('name:',name)
    }
    getName();
    ( async function(){
        const person=await '七個小矮人' //await Promise.resolve('七個小矮人') await后面不跟Promise,也會被封裝成Promise
        console.log('person:',person)//400
    })();//自執行函數
    
    //name: 白雪公主
    //person: 七個小矮人

    3、多個await時,按時序執行

    當函數執行的時候,一旦遇到await就會先返回,等到異步操作完成,再接著執行函數體內后面的語句。任何一個await語句后面的 Promise 對象變為reject狀態,那么整個async函數都會中斷執行。

    async function testOrder() {
        await Promise.reject('出錯了')//UnhandledPromiseRejectionWarning: 出錯了
        await Promise.resolve('hello world'); // 不會執行
    }
    testOrder();

    4、try…catch相當于catch

    如果希望即使前一個異步操作失敗,也不要中斷后面的異步操作。可將第一個await放在try...catch結構里面,這樣不管這個異步操作是否成功,第二個await都會執行。

    // try...catch
    !(async function () {
        const testError = Promise.reject('出錯啦~~~')//rejected狀態
        // const testError=throw new Error('出錯啦~~~');
        try {
            const result = await testError; //await相當于then,但是reject不會觸發then
            console.log('success:'+result) //不會輸出,因為const result = await testError被報錯,被catch捕獲
        } catch (error) {
            console.error('error:'+error)//try...catch 相當于Promise的catch
        }
    
    })()
    //error:出錯啦~~~

    當await后面是Promise對象的時候,我們也可直接在await后面直接.catch捕獲錯誤:

    async function testError() {
        await Promise.reject('出錯了')
            .catch(error => console.log(error));//這里捕獲錯誤,不會影響下一個await執行
        
        return await Promise.resolve('hello world');
    }
    
    testError()
        .then(result => console.log(result))

    三、解析Async-await語法

    我們淺淺看一個面試題:

    // 面試題
    function getJSON() {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                console.log(2);
                resolve(2)
            }, 2000)
        })
    }
    async function testAsync() {
        await getJSON()
        console.log(3);
    }
    testAsync()
    //2
    //3

    問題當然不會問打印順序啦,問題是將async await語句解析翻譯為Promise?

    根據現在的知識面,我們必須知道:

    (1)await不能單獨出現,其函數前面一定要有async。

    (2)await會干兩件事:

    第一,將寫在await后面的代碼放到async創建的那個Promise里面執行。

    第二、將寫在await下面的代碼放到前一個創建的那個Promise對象的.then里面執行。

    (3)await返回的也是Promise對象,他只是把await下面的代碼放到了await返回的promise的.then里面執行。

    這樣的話,是不是如魚得水了。翻譯如下:

    function getJSON() {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                console.log(2);
                resolve(2)
            }, 2000)
        })
    }
    // 編譯成Promise原理
    function testAsync() {
        return Promise.resolve().then(() => {
            return getJSON();
        })
            .then(() => {
                console.log(3);
    
            })
    }
    testAsync()

    四、拓展Async-await應用

    1、場景1

    你學廢async-await了嘛?還記得上一篇開篇的回調地獄嘛?我們通過Promise解決回調是這樣的:

    // Promise解決方式
    function doCallback(n) {
        var myPromise = new Promise(function (resolve, reject) {   
            //處理異步任務
            var flag = true;
            setTimeout(function () {
                if (flag) {
                    resolve(n)
                }
                else {
                    reject('失敗')
                }
            },0)
        })
        return myPromise;
    }
    
    doCallback(1)
        .then((result) => { //then是成功執行的方法 返回的還是一個Promise對象
            console.log(result);//打印張三  res是執行
            return fn(2);
        })
        .then((result) => {
            console.log(result);
            return fn(3)
        })
        .then((result) => {
            console.log(result);
            return fn(4)
        })
        .then((result) => {
            console.log(result);
        })
        .catch((result) => { //catch是失敗執行的方法
            console.log(result);
        })
        //好多.then,形成.then鏈啦
    //1
    //2
    //3
    //4

    通過以上Promise方法,可以明顯解決回調地獄“向右移”的浮夸表現,但是,Promise是基于 then, catch 的鏈式調用,但也是基于回調函數。.then鏈多多少少還是違背原生代碼,顯得也不是很優雅。作為回調終極武器,async-await更加貼近于原生代碼,我們看一下吧:

    //封裝一個返回promise的異步任務
    function doCallback(str) {
        var myPromise = new Promise(function (resolve, reject) {
            var flag = true;
            setTimeout(function () {
                if (flag) {
                    resolve(str)
                } else {
                    reject('處理失敗')
                }
            })
        })
        return myPromise;
    }
    
    //封裝一個執行上述異步任務的async函數
    async function testAsync() {
        var result1 = await doCallback(1);  //await直接拿到fn()返回的promise的數據,并且賦值給result
        var result2 = await doCallback(2);  //await 后面的代碼,都可以看做是異步回調 callback 里的內容,都是異步的
        var result3 = await doCallback(3);
        var result4 = await doCallback(4);
        console.log(result1);
        console.log(result2);
        console.log(result3);
        console.log(result4);
    }//這樣是不是簡潔優雅多了呢?
    //執行函數
    testAsync();
    //1
    //2
    //3
    //4

    以上就是“async-await消滅異步回調的方法”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    宜城市| 六枝特区| 南阳市| 汽车| 玉门市| 汝城县| 沛县| 藁城市| 大渡口区| 湖南省| 彰武县| 湘阴县| 晋城| 皮山县| 安阳市| 师宗县| 大荔县| 房山区| 屏南县| 莒南县| 周口市| 南溪县| 古蔺县| 丘北县| 永城市| 黑山县| 阿图什市| 永宁县| 怀集县| 五莲县| 东丰县| 青河县| 五华县| 塔城市| 龙游县| 奎屯市| 永康市| 都江堰市| 沈阳市| 金昌市| 沛县|