ES6基礎(chǔ)之a(chǎn)sync/await及Promise來(lái)處理異步方法數(shù)據(jù)

1. Promise來(lái)獲取異步方法中的數(shù)據(jù):

類似于將一個(gè)異步方法封裝在一個(gè)具有回調(diào)函數(shù)的函數(shù)里,Promise實(shí)際上充當(dāng)了這種封裝作用。然后通過resolve和reject函數(shù)向外輸出成功時(shí)的數(shù)據(jù)和失敗時(shí)的錯(cuò)誤信息,以Promise.then((data)=>{})來(lái)接收輸出的數(shù)據(jù),如下圖過程:

image

例如下面的代碼:

const p = new Promise((resolve, reject)=>{
    setTimeout(function(){
        const name = 'joyitsai';
        resolve(name);
    /*
    如果失敗reject輸出錯(cuò)誤信息
     reject(`error_info`)
    */
    }, 1000);
})
p.then((data)=>{
    console.log(data);
})

2. async/await與Promise:

所謂的Promise,把它想象成一個(gè)容器,里面放著一些正在處理的問題,但不管過多長(zhǎng)時(shí)間,它最終都會(huì)把它處理完成的結(jié)果(不管是成功還是失敗的)輸出給你,而且,它允許你通過.then((data)=>{})方法來(lái)接收這個(gè)結(jié)果數(shù)據(jù)。Promise可以說是為處理異步而生。

(1) 關(guān)于async

而所謂的async,它是將一個(gè)方法或函數(shù)變成異步的,它會(huì)將一個(gè)普通函數(shù)封裝成一個(gè)Promise,為什么要封裝成Promise呢?其實(shí)它只是Promise的搬運(yùn)工,利用了Promise處理異步問題的能力,能讓你更好地解決需要異步處理的代碼。。下面看一下簡(jiǎn)單的代碼:

/**async/await 與Promise */
async function testAsync(){
    return 'Here is Async';
}
const result = testAsync();
console.log(result);

執(zhí)行后,你將會(huì)看到:

Promise { 'Here is Async' }

既然async實(shí)際上是將一個(gè)普通函數(shù)封裝成了Promise,那么來(lái)獲取async封裝的這個(gè)異步方法的數(shù)據(jù)自然可以用Promise的.then()方法,接著上面的代碼,你可用result.then((data)=>{})來(lái)接收和處理得到的數(shù)據(jù)。
但是async的作用如果僅僅是這樣,那還要它干嘛?async其實(shí)是與await結(jié)合使用的,目的在于:直接返回異步方法中的數(shù)據(jù):

async function run(){
    const data = await testAsync();
    console.log(data)
}
run();

得到的data就是Here is Async。

(2) 關(guān)于await

  • async用來(lái)申明里面包裹的內(nèi)容可以進(jìn)行同步的方式執(zhí)行,await則是進(jìn)行執(zhí)行順序控制,每次執(zhí)行一個(gè)await,程序都會(huì)暫停等待await返回值,然后再執(zhí)行之后的await。
  • await后面調(diào)用的函數(shù)需要返回一個(gè)promise,另外這個(gè)函數(shù)是一個(gè)普通的函數(shù)即可,而不是generator。
  • await只能用在async函數(shù)之中,用在普通函數(shù)中會(huì)報(bào)錯(cuò)。
  • await命令后面的 Promise 對(duì)象,運(yùn)行結(jié)果可能是 rejected,所以最好把 await 命令放在 try...catch 代碼塊中。
關(guān)于await的理解:

await具有阻塞功能,可以理解為:等待await語(yǔ)句執(zhí)行完成后,后面的程序才會(huì)繼續(xù)。這就意味著,雖然一段包含await語(yǔ)句的異步程序,最終卻是按照同步的順序來(lái)執(zhí)行。
此外,await的阻塞,意味著它不能用在async以外的函數(shù)中,因?yàn)?code>await會(huì)嚴(yán)重影響非async(異步)程序的執(zhí)行效率,只能用在async函數(shù)中。

下面是await將異步變成同步的代碼段:

async function test(){
    console.log(2);
    return 'Joyitsai';
}

async function run(){
    console.log(1);
    const data = await test();
    console.log(data);
    console.log(3);
}
run();

打印結(jié)果為:

1
2
Joyitsai
3
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
   
</head>
<body>
    <div id="app">
        <div>
            {{courses}}
        </div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        //模擬異步數(shù)據(jù)的調(diào)用
        function getCourse(){
            return new Promise((resolve,reject)=>{
                setTimeout(()=>{
                    resolve(['vue','react1'])
                },1000);
            });
        }


        async function f1(){
            return 'abc'       //第一步理解:這種寫法系統(tǒng)會(huì)自動(dòng)包裝成promise對(duì)象  return newPromise((resolve)=>{resolve('abc')})
        }

        async function testAsync(){
            return "here is async"
        }
        const result = testAsync();
        console.log(result);
        result.then((data)=>{
            console.log('data...'+data)
        });

        //創(chuàng)建vue實(shí)例
        const app = new Vue({
            el:'#app',
            data(){
                return{
                    title:'jesse',
                    course:'',
                    courses:[],
                    totalCount:0
                }
            },
            async created(){
               const courses = await  getCourse(); 
               this.courses = courses;
               console.log( this.courses)  //這邊打印出來(lái)['vue','react1'],相當(dāng)于上面reslove里面的實(shí)參
            },
            methods:{

            }
        });
    </script>
</body>
</html>

promise中then的幾種返回值

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <script>
        let p = new Promise((resolve,reject)=>{
            resolve('123')
        })

        p.then((info)=>{
            console.log(info)
            // return 123;
            return new Promise((resolve,reject)=>{
                reject();
            })
        }).then((msg)=>{
            console.log('成功了',msg)
        },()=>{
            console.log('失敗了')
        })   

        // then的返回值 會(huì)有幾個(gè)不同的狀態(tài)  
        // 1. then 沒有返回值 就會(huì)默認(rèn)返回一個(gè)promise為resolve的實(shí)例 
        // 2. then 有返回值,但它的返回值不是promise 那他會(huì)給一個(gè) promise為resolve的實(shí)例 并且會(huì)將返回值傳給下一個(gè)then
        // 3. then 返回的是一個(gè)自定義promise,它會(huì)根據(jù)你最終的狀態(tài)決定走哪個(gè)函數(shù)

    </script>
</body>
</html>

在promise的reject之后會(huì)執(zhí)行catch,catch執(zhí)行之后會(huì)返回一個(gè)成功的promise所以會(huì)執(zhí)行catch之后的then,除非在catch里面顯式的返回一個(gè)reject之后才會(huì)執(zhí)行catch之后的catch

參考鏈接:https://blog.csdn.net/qq_15506981/article/details/112638756

image.png
  <script>
        window.onscroll = function () {
            console.log(this)
        }
        new Promise((resolve, reject) => {
            setTimeout(() => {
                reject();
            }, 1000)
        })
            .then(() => {
                console.log("1.成功了")
                throw new Error("第一個(gè)then出錯(cuò)")
            }, () => {
                console.log("1.失敗了");
                throw new Error("第一個(gè)then出錯(cuò)")
            })

            .then(() => {
                console.log("2.成功了")
            }, () => {
                console.log("2.失敗了");
                throw new Error("第2個(gè)then出錯(cuò)")
            })
            .catch((err) => {
                console.log(err)
            })
            .then(() => {
                console.log("3.成功了")
            }, () => {
                console.log("3.失敗了");
                throw new Error("第3個(gè)then出錯(cuò)")
            })

    </script>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容