欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript體驗異步更好的解決辦法

 更新時間:2018年01月08日 08:55:01   投稿:laozhang  
本篇文章主要給大家講述了JavaScript體驗異步更好的解決辦法,有這方面需要的朋友跟著學習參考下吧。

一、異步解決方案的進化史
JavaScript的異步操作一直是個麻煩事,所以不斷有人提出它的各種解決方案??梢宰匪莸阶钤绲幕卣{函數(ajax老朋友),到Promise(不算新的朋友),再到ES6的Generator(強勁的朋友)。
幾年前我們可能用過一個比較著名的Async.js,但是它沒有擺脫回調函數,并且錯誤處理也是按照“回調函數的第一個參數用來傳遞錯誤”這樣一個約定。而眾所周知的回調地獄仍然是一個比較突出的問題,直到Generator改變了這種異步風格。
但是ES7的async await的出現(碉堡的新朋友),我們可以輕松寫出同步風格的代碼同時又擁有異步機制,可以說是目前最簡單,最優(yōu)雅,最佳的解決方案了。

二、async await語法
async await語法比較簡單,可以認為是Generator的語法糖,比起星號和yield更具有語義化。下面一個簡單的例子表示1秒之后輸出hello world:

function timeout(ms) {
 return new Promise((resolve) => {
  setTimeout(resolve, ms);
 });
}
async function asyncPrint(value, ms) {
 await timeout(ms);
 console.log(value)
}
asyncPrint('hello world', 1000);

await只能用在async函數中,如果用在普通函數就會報錯

await后面跟的是一個Promise對象(當然其它值也可以,但是會包裝成一個立即resolve的Promise,也就沒有意義了)

await會等待Promise的結果返回再繼續(xù)執(zhí)行

await等待的雖然是Promise對象,但是不必寫.then(),直接可以得到返回值,將上面的代碼微調,發(fā)現返回值result也是可以輸出hello world:

function timeout(ms) {
 return new Promise((resolve) => {
  setTimeout(_ => {resolve('hello world')}, ms);
 });
}
async function asyncPrint(ms) {
 let result = await timeout(ms);
 console.log(result)
}
asyncPrint(1000);

三、async await錯誤處理

前面說了await等待的雖然是Promise對象,但是不必寫.then(),所以其實也不用寫.catch()了,直接用try catch就能捕捉錯誤,這樣可以避免錯誤處理代碼非常冗余和笨重,還是將上面的例子微調:

function timeout(ms) {
 return new Promise((resolve, reject) => {
  setTimeout(_ => {reject('error')}, ms);//reject模擬出錯,返回error
 });
}
async function asyncPrint(ms) {
 try {
   console.log('start');
   await timeout(ms);//這里返回了錯誤
   console.log('end');//所以這句代碼不會被執(zhí)行了
 } catch(err) {
   console.log(err); //這里捕捉到錯誤error
 }
}
asyncPrint(1000);

如果有多個await,可以一起放在try catch中:

async function main() {
 try {
  const async1 = await firstAsync();
  const async2 = await secondAsync();
  const async3 = await thirdAsync();
 }
 catch (err) {
  console.error(err);
 }
}

四、async await注意點

1). 前面已經說過,await命令后面的Promise對象,運行結果很可能是reject或邏輯報錯,所以最好把await放在try catch代碼塊中。

2). 多個await命令的異步操作,如果不存在依賴關系,讓它們同時觸發(fā)。

const async1 = await firstAsync();
const async2 = await secondAsync();

上面代碼中,async1和async2如果是兩個獨立的異步操作,這樣寫會比較耗時,因為只有firstAsync完成以后,才會執(zhí)行secondAsync,完全可以用Promise.all優(yōu)雅地處理:

let [async1, async2] = await Promise.all([firstAsync(), secondAsync()]);

3). await只能用在async函數之中,如果用在普通函數就會報錯:

async function main() {
 let docs = [{}, {}, {}];
 //報錯 await is only valid in async function
 docs.forEach(function (doc) {
  await post(doc);
  console.log('main');
 });
}
function post(){
 return new Promise((resolve) => {
  setTimeout(resolve, 1000);
 });
}

在forEach內部方法加上async就可以了:

async function main() {
 let docs = [{}, {}, {}];
 docs.forEach(async function (doc) {
  await post(doc);
  console.log('main');
 });
}
function post(){
 return new Promise((resolve) => {
  setTimeout(resolve, 1000);
 });
}

但是你會發(fā)現3個main是同時輸出的,這就說明post是并發(fā)執(zhí)行的,而不是繼發(fā)執(zhí)行,改成for就可以解決問題,3個main是分別相隔1秒輸出:

async function main() {
 let docs = [{}, {}, {}];
 for (let doc of docs) {
  await post(doc);
  console.log('main');
 }
}
function post(){
 return new Promise((resolve) => {
  setTimeout(resolve, 1000);
 });
}

總之,用了async await之后整個人神清氣爽,可以用非常簡潔和優(yōu)雅的代碼實現各種花式異步操作,并且在業(yè)務邏輯復雜的情況下可以不用陷入回調地獄中。不敢說這一定是終極的解決方案,但確實是目前最優(yōu)雅的解決方案!

相關文章

  • 微信小程序使用Vant Weapp組件庫的方法步驟

    微信小程序使用Vant Weapp組件庫的方法步驟

    這篇文章主要給大家介紹了關于微信小程序使用Vant Weapp組件庫的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用微信小程序具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-08-08
  • 微信小程序開發(fā)篇之踩坑記錄

    微信小程序開發(fā)篇之踩坑記錄

    這篇文章主要給大家介紹了關于微信小程序開發(fā)篇之踩坑記錄的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-03-03
  • 自用js開發(fā)框架小成 學習js的朋友可以看看

    自用js開發(fā)框架小成 學習js的朋友可以看看

    前段時間項目需要用到js樹,找了好多都不符合項目需求,后來發(fā)現了梅花雪樹和js框架,類似C#名稱空間的用法讓我眼前一亮,遂拿來主義,讀了幾遍代碼后就開工了(我是個急性子呵呵),完成了大部分,最近才找出來測試了下。
    2010-11-11
  • 深入理解JavaScript的事件執(zhí)行機制

    深入理解JavaScript的事件執(zhí)行機制

    本文主要介紹了JavaScript的事件執(zhí)行機制,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • js處理xml文件方法示例詳解

    js處理xml文件方法示例詳解

    這篇文章主要為大家介紹了js處理xml文件方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-08-08
  • JS設計模式之狀態(tài)模式的用法使用方法

    JS設計模式之狀態(tài)模式的用法使用方法

    JavaScript狀態(tài)模式是一種行為型設計模式,核心是對象在其內部狀態(tài)改變時改變其行為,狀態(tài)模式將對象的行為封裝到不同的狀態(tài)類中,使得對象在不同狀態(tài)下可以選擇不同的行為,本文給大家詳細的介紹一下狀態(tài)設計模式在Js中的使用,需要的朋友可以參考下
    2023-08-08
  • Vue.js實現頁面后退時還原滾動位置的操作方法

    Vue.js實現頁面后退時還原滾動位置的操作方法

    Vuet看起來也不是很復雜,只需要定義好模塊狀態(tài),然后在組件中設置對應的規(guī)則來更新模塊的狀態(tài)即可,這篇文章主要介紹了Vue.js實現頁面后退時還原滾動位置的實現方法,需要的朋友可以參考下
    2022-07-07
  • JavaScript運動框架 解決防抖動問題、懸浮對聯(二)

    JavaScript運動框架 解決防抖動問題、懸浮對聯(二)

    這篇文章主要為大家詳細介紹了JavaScript運動框架的第二部分,解決防抖動問題、懸浮對聯問題,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • 利用element-ui實現遠程搜索兩種實現方式

    利用element-ui實現遠程搜索兩種實現方式

    這篇文章主要介紹了利用element-ui的兩種遠程搜索實現代碼,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2023-12-12
  • 學習JS中的DOM節(jié)點以及操作

    學習JS中的DOM節(jié)點以及操作

    本篇文章給大家整理了關于JS中DOM節(jié)點的相關知識點以及代碼實例,有興趣的朋友可以跟著學習下。
    2018-04-04

最新評論