摘要:立即執(zhí)行的驗證的參數(shù)是異步調(diào)用的驗證當(dāng)在中通過調(diào)用使?fàn)顟B(tài)穩(wěn)定之后,不管調(diào)用多少次,值都不會再發(fā)生變化一諾千金的優(yōu)點是什么我看了很多文章在介紹的時候都會提到回調(diào)噩夢。
TL;DR
本文是對 Promise 一些概念點的歸納和對 Promise 在解決什么問題的思考。
并不會介紹 Promise 的 Api。
一直想寫一篇關(guān)于 Promise 的文章,但覺得自己對 Promise 是一知半解,始終擱置。前幾天剛好在看 Dr. Axel Rauschmayer 的『 Exploring ES6 』 這本書的時候,看到關(guān)于 Promise 的章節(jié),仔細讀了一遍,又動手實現(xiàn)了簡易版的 Promise 一遍,再印證其它的資料,這才開始完成這篇文章。
要知道 Promise 哪些知識點const p = new Promise( function (resolve, reject) { // (A) ··· if (···) { resolve(value); // success } else { reject(reason); // failure } })
A 行的函數(shù)被稱為 executor
當(dāng)實例化一個 Promise 的時候,executor 總是「立即執(zhí)行」的
Promises 總是異步執(zhí)行的。在 then 的消耗 Promise value 時候,會把 then 的參數(shù)放到任務(wù)隊列中,等待執(zhí)行。
當(dāng) Promise 中的狀態(tài)進入穩(wěn)定態(tài)(settled)的時候,Promise 的值便不會再發(fā)生變化,這就是 Promise 的名稱由來:承諾。
// executor 立即執(zhí)行的驗證 new Promise( (res) => { console.log(1) setTimeout(() => console.log(3), 1000) }) console.log(2) // ------> 1 // ------> 2 // ------> 3 // then 的參數(shù)是異步調(diào)用的驗證 new Promise( (res) => { res(2) }).then(v=> console.log(v)) console.log(1) // ------> 1 // ------> 2 // 當(dāng)在 executor 中通過調(diào)用 res 使?fàn)顟B(tài)穩(wěn)定之后,不管調(diào)用多少次 res,值都不會再發(fā)生變化 new Promise( (res) => { res(1) res(2) }).then(v=> console.log(v)) // ------> 1Promise -- 一諾千金
Promise 的優(yōu)點是什么?我看了很多文章在介紹 Promise 的時候都會提到回調(diào)噩夢(Callback Hell)。然而我覺得 Promise 并沒有簡單的解決回調(diào)噩夢的問題,寫 then 往往比寫 callback 更惡心。
在我看來,Promise 提供了控制反轉(zhuǎn)的機會。
假設(shè)有下面這樣一個函數(shù),10 秒后調(diào)用傳入的 fn。這是一個你的同事提供給你的獨立文件。
// foo.js function foo(fn) { setTimeout(fn, 1000*10) } module.exports = foo
你在寫一個 10 秒之后打印 log 的業(yè)務(wù):
var foo = require("foo") foo(()=> console.log("hello,world!!"))
然而很不幸,你的同事離職,他的代碼被交給一個很笨的新同事維護,新同事維護這個代碼的時候,不小心復(fù)制了一行代碼:
// foo.js function foo(fn) { setTimeout(fn, 1000*10) setTimeout(fn, 1000*10) } module.exports = foo
這時每次調(diào)用 foo 的時候,都會寫兩遍日志,不到 1 天服務(wù)器的硬盤就被撐爆了,用戶就不能訪問網(wǎng)頁了,接著用戶就流失了,公司倒閉了,你就被失業(yè)了,想想都是很可怕的事情。這些都是因為你把你的函數(shù)交給你的同事調(diào)用并且無條件信任他。
然而 Promise 會怎樣做?
// foo.js function foo() { return new Promise((res) => { setTimeout(res, 1000*2) }) } module.exports = foo // main.js var foo = require("foo") foo().then(()=> console.log("hello,world!!"))
那個笨同事又干了同樣的蠢事,這次他復(fù)制了三行:
// foo.js function foo() { return new Promise((res) => { setTimeout(res, 1000*10) setTimeout(res, 1000*10) setTimeout(res, 1000*10) }) } module.exports = foo
然而這次讓我失業(yè)的行為并沒有得逞,因為當(dāng) Promise 的狀態(tài)穩(wěn)定之后,值就不會再改變,不管調(diào)用多少次 reslove 方法都是同樣的效果。Callback 會把你做的事情的權(quán)限交出去,你不再對你的函數(shù)有控制權(quán),而 Promise 是在等狀態(tài)穩(wěn)定之后才會再去執(zhí)行你自己的函數(shù),你對此函數(shù)擁有控制權(quán)。
不過說到底,都沒有絕對的信任,也說不定有人會把 Promise 的 then 實現(xiàn) hack 了,而這種惡意做法的成本要比他不小心多復(fù)制一行代碼的成本要高得多。
Exploring ES6
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/79528.html
摘要:瀏覽器對象可以獲取瀏覽器提供的很多對象,并進行操作。對象不但充當(dāng)全局作用域,而且表示瀏覽器窗口。對象表示當(dāng)前頁面的信息。由于在瀏覽器中以形式表示為樹形結(jié)構(gòu),對象就是整個樹的根節(jié)點。這個行為由瀏覽器實現(xiàn),主流瀏覽器均支持選項,從開始支持。 由于JavaScript的出現(xiàn)就是為了能在瀏覽器中運行,所以,瀏覽器自然是JavaScript開發(fā)者必須要關(guān)注的。【寫的比較多,難免有疏漏的地方,希望...
摘要:軟件測試零基礎(chǔ)學(xué)習(xí)難不難其實,如果你想轉(zhuǎn)到行業(yè),其實軟件測試是最簡單的學(xué)科之一,很適合零基礎(chǔ)學(xué)習(xí),只要你有一顆好奇的心肯學(xué)習(xí)的心和對軟件測試充滿興趣,難度不會太大。 ...
摘要:凡有所學(xué),皆成性格。關(guān)于作者陳光劍,江蘇東海人號行走江湖一劍客,字之劍。程序員,詩人作家。光劍免費圖書館創(chuàng)始人天才郵箱如果您有好的書籍推薦請聯(lián)系我 WFeB全球免費圖書館 World Free eBook 全球免費開放的電子圖書館(https://universsky.github.io/) 道之所在,雖千萬人吾往矣;義之所當(dāng),千金散盡不后悔;情之所鐘,世俗禮法如糞土;興之所至,與君痛...
摘要:凡有所學(xué),皆成性格。關(guān)于作者陳光劍,江蘇東海人號行走江湖一劍客,字之劍。程序員,詩人作家。光劍免費圖書館創(chuàng)始人天才郵箱如果您有好的書籍推薦請聯(lián)系我 WFeB全球免費圖書館 World Free eBook 全球免費開放的電子圖書館(https://universsky.github.io/) 道之所在,雖千萬人吾往矣;義之所當(dāng),千金散盡不后悔;情之所鐘,世俗禮法如糞土;興之所至,與君痛...
閱讀 3617·2023-04-25 23:32
閱讀 2039·2019-08-30 15:55
閱讀 2651·2019-08-30 15:52
閱讀 3110·2019-08-30 10:54
閱讀 839·2019-08-29 16:16
閱讀 646·2019-08-29 15:09
閱讀 3647·2019-08-26 14:05
閱讀 1632·2019-08-26 13:22