摘要:但是中的這種情況與抽象反應(yīng)器模式如何描述完全不同。在處理一個階段之后并且在移到下一個隊列之前,事件循環(huán)將處理兩個中間隊列,直到中間隊列中沒有剩余的項目。如果沒有任務(wù)則循環(huán)退出,每一次隊列處理都被視為事件循環(huán)的一個階段。
Promise && async/await的理解和用法 為什么需要promise(承諾)這個東西
在之前我們處理異步函數(shù)都是用回調(diào)這個方法,回調(diào)嵌套的時候會發(fā)現(xiàn) 閱讀性 和 調(diào)試 的難度會增加很多;怎么理解promise
想象一下,你把一個任務(wù)交給一個不錯的小伙子,他叫承諾;不用擔(dān)心你交給他的任務(wù)會丟失,他總會返回的,做成功了resolve,失敗了reject;
var promise = new Promise((resolve, reject) =>{ //交給給“承諾”同學(xué)一個異步任務(wù) setTimeout(()=>{ if(true){ // 成功了,返回params resolve("params") }else{ // 失敗了,返回error reject("error") } }, 1000) }) // 上面是給承諾一個任務(wù),下面是"承諾"同學(xué)的返回 promise.then((res)=>{ console.log(res) }).catch((rej)=>{ console.log(res) })怎么使用promise
實際情況中,異步的場景沒有那么簡單,你可以會遇到下面這些場景
“串行應(yīng)用場景”下的處理方案
let promise = new Promise((res, rej)=>{ asyncFunc("promise", 1000, res, rej) }) promise.then(res=>{ console.log(res); return new Promise((res, rej)=>{ asyncFunc("second", 2000, res, rej) }) }).then(res=>{ console.log(res); return new Promise((res, rej)=>{ asyncFunc("third", 1000, res, rej) }) // throw "oh, no!"; }).then(res=>{ console.log(res); console.log("endinggggggg") }).catch(err=>{ console.log("catch", err) })
“并行應(yīng)用場景”的處理方案(即在所有的異步操作完成之后執(zhí)行)
let promise1 = new Promise((res, rej)=>{ asyncFunc("promise1", 1000, res, rej) }) let promise2 = new Promise((res, rej)=>{ asyncFunc("promise2", 2000, res, rej) }) let promise3 = new Promise((res, rej)=>{ asyncFunc("promise3", 1000, res, rej) }) var promiseAll = Promise.all([promise1, promise2, promise3]) promiseAll.then(res =>{ console.log("最終的結(jié)果", res) }).catch(err =>{ console.log("catch", err); })
“競速模式下”,如字面意思,只要是哪一個提前完成了。就表示整個狀態(tài)處理完成狀態(tài);這個場景可以發(fā)散成如果是超過了3s我就不去做這件事情了
let promise1 = new Promise((res, rej)=>{ asyncFunc("promise1", 1000, res, rej, true) }) let promise2 = new Promise((res, rej)=>{ asyncFunc("promise2", 2000, res, rej, true) }) let promise3 = new Promise((res, rej)=>{ asyncFunc("promise3", 1000, res, rej) }) // 1000s的任務(wù)完成了,就直接返回promise1了 var promiseRace = Promise.race([promise1, promise2, promise3]) promiseRace.then(res =>{ console.log("最終的結(jié)果", res) }).catch(err =>{ console.log("catch", err); })js是單線程,promise,setTimeout的執(zhí)行優(yōu)先級
講這一塊的東西就得講講nodejs的事件處理機制;
事件隊列應(yīng)該是一個數(shù)據(jù)結(jié)構(gòu),所有的事情都被事件循環(huán)排隊和處理,直到隊列為空。但是Node中的這種情況與抽象反應(yīng)器模式如何描述完全不同。
下面講的東西只適合V8;
NodeJS中有許多隊列,其中不同類型的事件在自己的隊列中排隊。
在處理一個階段之后并且在移到下一個隊列之前,事件循環(huán)將處理兩個中間隊列,直到中間隊列中沒有剩余的項目。
有四種主要類型,由libuv事件循環(huán)處理;
過期的定時器和間隔隊列 - (比如使用setTimeout,setInterval);
IO事件隊列 - 已完成的IO事件
Immediates隊列 - 使用setImmediate功能添加回調(diào)
關(guān)閉處理程序隊列 - 任何close事件處理程序
還有2個中間隊列,不屬于libuv本身的一部分,但是是nodejs的一部分;
Next Ticks Queue - 使用process.nextTick 函數(shù)添加回調(diào);(優(yōu)先級更高)
其他微型任務(wù)隊列 - 包括其他微型任務(wù),例如已經(jīng)解決的承諾回調(diào);
上圖是node中l(wèi)ibuv模塊在處理異步I/O操作的流程圖;
Node通過定時器檢查隊列中的任何過期定時器來啟動事件循環(huán),并在每一個步驟中遍歷每一個隊列。如果沒有任務(wù)則循環(huán)退出,每一次隊列處理都被視為事件循環(huán)的一個階段。特別有意思的是中間紅色的隊列,每次階段都會優(yōu)先去處理中間隊列的任務(wù)。然后再去處理其他的隊列。
什么是async/awaitasync/await 可以是Generator和promise結(jié)合實現(xiàn)的;注意核心點:
asnyc 函數(shù)總是返回一個Promise對象,不論函數(shù)是否return Promise;
await 后面跟著Promise對象,如果不是Promise對象,也會被封裝成Promise;
async/await 和Promise對象在本質(zhì)上是一樣的
await的任何內(nèi)容都通過Promise.resolve()傳遞,這樣就可以安全的await非原生Promise;
構(gòu)造函數(shù)以及getter/settings方法不能是異步的;
盡管編寫的是同步的代碼,但是也不要錯失并行執(zhí)行的機會,不然你需要消耗等待的性能喪失;
Babel REPL 說起來很有趣。試試就知道。
怎么用async/await實際情況中,異步的場景沒有那么簡單,你可以會遇到下面這些場景
場景:只有一個await并且 resolve
const delay = timeout => new Promise(resolve => setTimeout(resolve, timeout)); async function f(){ await delay(1000); await delay(2000); await delay(3000); return "done" } f().then(v=> console.log(v));
場景:只有一個await并且 reject
let a; async function g(){ await Promise.reject("error"); a = await 1; } g().then(v=>console.log(v)).catch(err=>console.log(err));
場景:有多個await, 可以用try/catch
let a ; async function g(){ try{ await Promise.reject("error") }catch(err){ console.log(err) } a= await 1; return a; } g().then(v=>console.log(v)).catch(err=>console.log(err));
場景:等待平行任務(wù)
async function series(){ const await1 = delay(1000); const await2 = delay(1000); await await1; await await2; return "done" } series();歡迎提意見和star
如果有不對的可以提issue
如果覺得對你有幫助可以star下
github
這一系列的文檔講的很不錯
https://juejin.im/post/5b777f...
講promise,setTimeout優(yōu)先級的;nodejs中事件循環(huán)中的任務(wù)優(yōu)先級
https://jsblog.insiderattack....
developers.google.com域名下面的文檔還是很有質(zhì)量的,其中會比較全面的介紹怎么去用promise和async/await
https://developers.google.com...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/108414.html
摘要:但是提出標(biāo)準(zhǔn),允許腳本創(chuàng)建多個線程,但是子線程完全受主線程控制。只是將事件插入了任務(wù)隊列,必須等到當(dāng)前代碼執(zhí)行棧執(zhí)行完,主線程才會去執(zhí)行它指定的回調(diào)函數(shù)。之后全局上下文進入函數(shù)調(diào)用棧。 setTimeout 一、setTimeout 初現(xiàn) 定義:setTimeout() 方法用于在指定的毫秒數(shù)后調(diào)用函數(shù)或計算表達式。 語法: setTimeout(code, millisec...
摘要:最近項目中用的比較多,所以特地去了解,模仿一下實現(xiàn)先來看看使用的方法通過是通過使用生成器配合方法模擬的一個同步操作,這個技術(shù)有效的避免了傳統(tǒng)回調(diào)和形成的回調(diào)地獄。 最近項目中 asyn & await 用的比較多,所以特地去了解,模仿一下實現(xiàn)~ 先來看看 使用 async & await 的方法 async function d () { try { const a = a...
摘要:和的關(guān)系和的關(guān)系非常的巧妙,必須在內(nèi)使用,并裝飾一個對象,返回的也是一個對象。的會使得的代碼節(jié)點自動拋出相應(yīng)的異常,終止向下繼續(xù)執(zhí)行。示例方法內(nèi)無節(jié)點沒有修飾的方法內(nèi)有節(jié)點注意內(nèi)的對節(jié)點的作用。 假設(shè)我們有三個請求,req1,req2, req3,三個請求后者依賴前者的請求結(jié)果。我們先使用Promise封裝一個異步請求的方法。 Promise 異步請求 使用Promise可以非常容易的...
摘要:的出現(xiàn),讓我們可以走出回調(diào)地獄,著實驚艷。我已經(jīng)開始使用里的和關(guān)鍵字來簡化的處理。異步任務(wù)在這個例子是執(zhí)行之后,一直在執(zhí)行完成才繼續(xù)下一個任務(wù)并沒有產(chǎn)生阻塞。最后這個函數(shù)處理了返回值并且返回了一個對象。依然很棒,但和使得它可維護性更好。 JavaScript Promises的出現(xiàn),讓我們可以走出回調(diào)地獄,著實驚艷。Promises 允許我們更好的引入和處理異步任務(wù),雖然如此,但引入好...
摘要:前文該系列下的前幾篇文章分別對不同的幾種異步方案原理進行解析,本文將介紹一些實際場景和一些常見的面試題。流程調(diào)度里比較常見的一種錯誤是看似串行的寫法,可以感受一下這個例子判斷以下幾種寫法的輸出結(jié)果辨別輸出順序這類題目一般出現(xiàn)在面試題里。 前文 該系列下的前幾篇文章分別對不同的幾種異步方案原理進行解析,本文將介紹一些實際場景和一些常見的面試題。(積累不太夠,后面想到再補) 正文 流程調(diào)度...
閱讀 3517·2021-11-25 09:43
閱讀 1273·2021-09-08 09:45
閱讀 2648·2021-09-07 09:59
閱讀 1509·2021-08-09 13:45
閱讀 3350·2019-08-30 15:54
閱讀 699·2019-08-29 18:35
閱讀 518·2019-08-29 17:18
閱讀 1002·2019-08-29 14:10