摘要:方法而對(duì)象本身,有一些方法查看的原型,發(fā)現(xiàn)它內(nèi)置有幾個(gè)方法參數(shù)處理成功的函數(shù),處理錯(cuò)誤的函數(shù)返回值返回一個(gè)對(duì)象,所以可以鏈?zhǔn)秸{(diào)用。參數(shù)返回值的參數(shù)應(yīng)該是函數(shù),傳入非函數(shù)則會(huì)發(fā)生值穿透。
前言
網(wǎng)上關(guān)于Promise的文章確實(shí)是非常多了,但是自己實(shí)踐的并不多,這里是針對(duì)自己的一個(gè)知識(shí)點(diǎn)小結(jié)和梳理,當(dāng)然啦如果有錯(cuò)誤歡迎提出^_^。
初定義定義:Promise對(duì)象用于一個(gè)異步操作的最終完成/失敗及其結(jié)果值的表示。
使用原因:避免回調(diào)嵌套層次過(guò)多。
擁有狀態(tài):
pending:初始/未定狀態(tài),初始化Promise時(shí),調(diào)用executor函數(shù)后的狀態(tài)。
fulfilled:成功狀態(tài)。
rejected:失敗狀態(tài)。
狀態(tài)轉(zhuǎn)化:
pending -> fulfilled:操作成功
pending -> rejected:操作失敗
狀態(tài)轉(zhuǎn)化是單向的,不可逆轉(zhuǎn)。
最基本用法:
可以看到創(chuàng)建一個(gè)Promise實(shí)例,傳入的參數(shù)是一個(gè)函數(shù),這個(gè)函數(shù)稱為executor/執(zhí)行器。
new Promise((resolve, reject) => { if (success) { resolve(a) // pending to resolved } else { reject(err) // pending to rejectd } })方法
而Promise對(duì)象本身,有一些方法:
race()
reject()
resolve()
all()
查看Promise的原型,發(fā)現(xiàn)它內(nèi)置有幾個(gè)方法:
catch()
finally()
then()
Promise.prototype.then()參數(shù):處理成功的函數(shù),處理錯(cuò)誤的函數(shù)
返回值:返回一個(gè)Promise對(duì)象,所以可以鏈?zhǔn)秸{(diào)用。
promise.then( () => { console.log("我是成功后被執(zhí)行的") }, () => { console.log("我是失敗后被執(zhí)行的") })Promise.prototype.catch()
參數(shù):捕捉的錯(cuò)誤/reject()傳來(lái)的參數(shù)
返回值:返回一個(gè)Promise對(duì)象,所以可以鏈?zhǔn)秸{(diào)用。
Promise和then()中拋出錯(cuò)誤能夠不斷傳遞,就能夠在下一個(gè)catch()中統(tǒng)一處理,所以一般省略then中的第二個(gè)失敗執(zhí)行的函數(shù)。
promise.then( () => { console.log("我是成功后被執(zhí)行的") } ).catch( (err) => { console.log(err) })
使用rejects()方法改變狀態(tài)和拋出錯(cuò)誤 throw new Error() 的作用是相同的Promise.all()
參數(shù):可迭代參數(shù),如:數(shù)組。
用途:處理一些并發(fā)的異步操作,需要保證每個(gè)都執(zhí)行完畢。
結(jié)果:狀態(tài)全為fulfilled->fulfilled,否則->rejected。
Promise.race()參數(shù):可迭代參數(shù),如:數(shù)組。
用途:處理一些并發(fā)的異步操作,只需要其中一個(gè)執(zhí)行完畢。
結(jié)果:所有異步操作中有一個(gè)狀態(tài)先改變,就采納那個(gè)最先改變的狀態(tài)為結(jié)果。
Promise.resolve()參數(shù):普通值、Promise對(duì)象、帶有then的對(duì)象。
結(jié)果:一般情況返回一個(gè)狀態(tài)為fulfilled的Promise對(duì)象。解析發(fā)生錯(cuò)誤則返回rejected的Promise對(duì)象。
Promise.resolve("success") // 其中[[PromiseStatus]]:"resolved" Promise.reject("fail") // 其中[[PromiseStatus]]:"rejected" Promise.resolve(Promise.reject("fail")) // 其中[[PromiseStatus]]:"rejected"
由這個(gè)例子可以看出瀏覽器認(rèn)為resolved和fulfilled是等價(jià)的,但Promise.resolve() 不一定讓promise最終是fulfilled。所以對(duì)于resolved本身和fulfilled的區(qū)別,可以理解為resolved等價(jià)于compiled,即可能是成功也可能是失敗。
Promise.reject()參數(shù): 發(fā)生異常的原因。
結(jié)果:返回一個(gè)rejected狀態(tài)的Promise對(duì)象。
注意點(diǎn) 狀態(tài)變化Promise狀態(tài)只會(huì)改變一次。
構(gòu)造函數(shù)中的resolve()/reject()只有第一次執(zhí)行有效,多次調(diào)用沒(méi)有作用。
Promise狀態(tài)改變,并且傳遞了一個(gè)值,后續(xù)調(diào)用.then()/.catch()都可直接拿到該值。
參數(shù)/返回值.then()/.catch()的參數(shù)應(yīng)該是函數(shù),傳入非函數(shù)則會(huì)發(fā)生值穿透。
Promise.resolve(1) .then(2) .then(Promise.resolve(3)) .then(console.log) //1
.then()/.catch()不能返回Promise本身,會(huì)造成死循環(huán)。
.then()/.catch()中return一個(gè)error對(duì)象并不會(huì)拋出錯(cuò)誤,所以無(wú)法捕捉。
因?yàn)榉祷厝我庖粋€(gè)非Promise 的值都會(huì)被包裹成Promise對(duì)象,即 return new Error("error!!!")等價(jià)于return Promise.resolve(new Error("error!!!"))執(zhí)行順序
Promise構(gòu)造函數(shù)是同步執(zhí)行的,resolve()/reject()后的代碼也會(huì)執(zhí)行。Promise.then()中的函數(shù)是異步執(zhí)行的。**
以下輸出:1243
const promise = new Promise((resolve, reject) => { console.log(1) resolve() console.log(2) }) promise.then(() => { console.log(3) }) console.log(4)
process.nextTick和promise.then屬于microtask,setImmediate屬于 macrotask。在每一次事件循環(huán)中,macrotask只會(huì)提取一個(gè)執(zhí)行,而microtask會(huì)一直提取,直到microsoft隊(duì)列為空為止。
以下輸出:end nextTick then setTimeout1 setTimeout2
process.nextTick(() => { console.log("nextTick") }) setTimeout(() => { console.log("setTimeout1") }) Promise.resolve() .then(() => { console.log("then") }) setTimeout(() => { console.log("setTimeout2") }) console.log("end")
補(bǔ)充:
macrotasks:
setTimeout
setInterval
setImmediate
requestAnimationFrame
I/O
UI rendering
microtasks:
process.nextTick
Promises
Object.observe
MutationObserver
參考文章ES6關(guān)于Promise的用法
Promise 必知必會(huì)(十道題)
javascript中的異步 macrotask 和 microtask 簡(jiǎn)介
Tasks, microtasks, queues and schedules
Difference between microtask and macrotask within an event loop context
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/108060.html
摘要:作者珂珂滬江前端開(kāi)發(fā)工程師本文為原創(chuàng)文章,有不當(dāng)之處歡迎指出。只對(duì)未來(lái)發(fā)生的事情做出兩種基本情況的應(yīng)對(duì)成功和失敗。在異步轉(zhuǎn)同步這條道路上,只是一個(gè)出彩的點(diǎn),他還尚有一些缺陷和不足,并不是我們最終的解決方案。 作者:珂珂 (滬江前端開(kāi)發(fā)工程師)本文為原創(chuàng)文章,有不當(dāng)之處歡迎指出。轉(zhuǎn)載請(qǐng)標(biāo)明出處。 一個(gè)新事物的產(chǎn)生必然是有其歷史原因的。為了更好的以同步的方式寫(xiě)異步的代碼,人們?cè)贘S上操碎了...
摘要:概述在之前,在中的異步編程都是采用回調(diào)函數(shù)和事件的方式,但是這種編程方式在處理復(fù)雜業(yè)務(wù)的情況下,很容易出現(xiàn)回調(diào)地獄,使得代碼很難被理解和維護(hù)。如果不設(shè)置回調(diào)函數(shù),內(nèi)部的錯(cuò)誤不會(huì)反應(yīng)到外部。 本文是基于對(duì)阮一峰的Promise文章的學(xué)習(xí)整理筆記,整理了文章的順序、增加了更多的例子,使其更好理解。 1. 概述 在Promise之前,在js中的異步編程都是采用回調(diào)函數(shù)和事件的方式,但是這種編...
摘要:不同瀏覽器下的限制策略和方案的整理端瀏覽器的限制策略和應(yīng)對(duì)方案使用在端測(cè)試的瀏覽器包括瀏覽器瀏覽器瀏覽器瀏覽器限制策略內(nèi)容參考自年月份發(fā)布的正式關(guān)掉了聲音自動(dòng)播放靜音自動(dòng)播放總是允許的。 不同瀏覽器下 autoplay 的限制策略和方案的整理 PC 端瀏覽器的限制策略 和 應(yīng)對(duì)方案 使用 Mac 在 PC 端測(cè)試的瀏覽器包括 Chrome 瀏覽器 Safari 瀏覽器 Firefox...
摘要:以下總結(jié)了異步編程的種方式回調(diào)函數(shù)回調(diào)函數(shù)異步編程的最基本的方式。由小組的成員在規(guī)范中提出,目的是為異步編程提供統(tǒng)一接口。結(jié)尾參考文章異步編程參考文章使用詳解 前言 Javascript語(yǔ)言的執(zhí)行環(huán)境是單線程。 單線程: 一次只能完成一個(gè)任務(wù)。如果有多個(gè)任務(wù),就必須排隊(duì),前面一個(gè)任務(wù)完成,再執(zhí)行后面一個(gè)任務(wù)。 單線程的好處是執(zhí)行環(huán)境簡(jiǎn)單,壞處是在一些耗時(shí)的任務(wù)上會(huì)堵塞進(jìn)程。比如讀取一個(gè)...
閱讀 2421·2021-11-25 09:43
閱讀 1255·2021-11-24 09:39
閱讀 756·2021-11-23 09:51
閱讀 2391·2021-09-07 10:18
閱讀 1881·2021-09-01 11:39
閱讀 2784·2019-08-30 15:52
閱讀 2599·2019-08-30 14:21
閱讀 2865·2019-08-29 16:57