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