網易雲音樂數據交互—async&await實現版(終結篇)
我們的網易雲音樂系列內容,尾聲了,今天我們要將一個最重要的東西--關於ES7 async結合Fetch非同步編程問題。
ES7 async/await被稱作非同步編程的終極解決方案,我們先不管這個稱呼,咱們先總結一下,過去5次分享我們一路走來非同步編程是如何產生,到最後如何解決的。
第一次分享我們學會了切圖和動態計算響應式rem布局,第二次分享我們體會了如何學習使用原生js進行學習輪播圖,第三次分享了H5 audio這塊,進而引出了第四次的非同步請求歌詞ajax和第五次的Fetch+promise解決方案。
但是每一種方案都不完美,我們通過代碼來說明。
<!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>
<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 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>
<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 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>
<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 讓我們跟我們寫日常普通代碼一樣寫非同步代碼呢?