網易雲音樂資料互動—async&await實現版

markriver發表於2021-09-09

網易雲音樂資料互動—async&await實現版(完結篇)

我們的網易雲音樂系列課,尾聲了,今天我們要將一個最重要的東西--關於ES7 async結合Fetch非同步程式設計問題。

ES7 async/await被稱作非同步程式設計的終極解決方案,我們先不管這個稱呼,我們們先總結一下,過去5次分享我們一路走來非同步程式設計是如何產生,到最後如何解決的。

第一次分享我們學會了切圖和動態計算響應式rem佈局,第二次分享我們體會了如何學習使用原生js進行學習輪播圖,第三次分享了H5 audio這塊,進而引出了第四次的非同步請求歌詞ajax和第五次的Fetch+promise解決方案。

網易雲音樂資料互動—async&await實現版(完結篇)

但是每一種方案都不完美,我們透過程式碼來說明。

<!DOCTYPE html>

<html>

<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>

    <script>

        var a = 12;

        //模擬資料互動需要等1秒鐘

        function loadData() {

            setTimeout(function () {

                a = 666;

            }, 1000)

        }

        loadData();

        console.log(a);

    </script>

</head>

<body>

</body>

</html>

不用想,這個結果就是 12 而不是666,因為程式不會等1s才往下執行,但是有時候又必須使用資料,所以只能巢狀。但是巢狀多了又會出現下面的問題,案例來自SF的朋友,特此感謝。

<!DOCTYPE html>

<html>

<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>

    <script>

        setTimeout(function () {

            console.log("第一個非同步回撥了!")

            setTimeout(function () {

                console.log("第二個非同步回撥了!")

                setTimeout(function () {

                    console.log("第三個非同步回撥了!")

                    setTimeout(function () {

                        console.log("第四個非同步回撥了!")

                        setTimeout(function () {

                            console.log("第五個非同步回撥了!")

                        }, 1000);

                    }, 1000);

                }, 1000);

            }, 1000);

        }, 1000);

    </script>

</head>

<body>

</body>

</html>

我特意寫了一個程式,這下大家就能體會他的缺陷。

那我們怎麼解決呢?

<!DOCTYPE html>

<html>

<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>

    <script>

        function timeout(ms) {

            return new Promise((resolve, reject) => {

                setTimeout(resolve, ms, "finish");

            });

        }

        timeout(2000)

            .then(value => {

                console.log("第一層" + value);

                return timeout(2000);

            })

            .then(value => {

                console.log("第二層" + value);

                return timeout(2000);

            })

            .then(value => {

                console.log("第三層" + value);

                return timeout(2000);

            })

            .then(value => {

                console.log("第四層" + value);

                return timeout(2000);

            })

            .then(value => {

                console.log("第五層" + value);

                return timeout(2000);

            })

            .catch(err => {

                console.log(err);

            });

    </script>

</head>

<body>

</body>

</html>

Promise改成了鏈式,但是不夠完美,重點來了,今天的知識如何使用ES7 的async和await 讓我們跟我們寫日常普通程式碼一樣寫非同步程式碼呢?

大家發現了吧,這樣寫是不是正確並且簡單了啊,僅僅是加了兩個單詞而已,完整程式碼

<!DOCTYPE html>

<html>

<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>

    <script>

        function timeout(ms) {

            return new Promise((resolve, reject) => {

                setTimeout(resolve, ms, "finish");

            });

        }

        async function asyncTimeSys() {

            await timeout(1000);

            console.log("第一層非同步結束!")

            await timeout(1000);

            console.log("第二層非同步結束!")

            await timeout(1000);

            console.log("第三層非同步結束!")

            await timeout(1000);

            console.log("第四層非同步結束!")

            await timeout(1000);

            console.log("第五層非同步結束!")

            return "all finish";

        }

        asyncTimeSys().then((value) => {

            console.log(value);

        });

    </script>

</head>

<body>

</body>

</html>

好,我們不整沒用的我們看看實際專案裡面怎麼搞的,還是拿網易雲舉例:

網易雲音樂資料互動—async&await實現版(完結篇)

ok,感覺天都亮了。

簡單吧,透過這個系列課程的學習大家已經完整的瞭解了一個專案的大體開發過程,同時也瞭解了一些容易出錯的方方面面,重點是涵蓋了ES6和ES7的新知識。

當然,完全靠我講大家體會不深,還是希望大家能夠真的自己認真練習,把這個專案做出來,而不是變成聽聽而已。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/818/viewspace-2818967/,如需轉載,請註明出處,否則將追究法律責任。

相關文章