Promise學習筆記(知識點 + 手寫Promise)
Promise標準瞭解一下
傳送門️
傳送門️
Promise重點難點
Promise的狀態不受外界影響,只由Promise內的非同步操作結果決定。
-
Promise的狀態一旦改變就不會再變。
pending fulfilled
pending rejected
Promise的建構函式是同步的,then()方法中的函式是非同步的。
then()方法或者catch()方法的引數期望是函式,傳入非函式則會發生值穿透
-
Promise屬於microtask,同一次事件迴圈中,microtask永遠在macrotask之前執行。
傳送門
手寫promise
實現基本狀態(pending, fulfilled, rejected)
-
實現then方法
返回一個promise,實現鏈式呼叫
實現狀態判斷
-
實現resolve函式
接受一個Promise作為引數時的情況,實現鏈式Promise
執行回撥函式時使用setTimeout,保證在註冊then方法後觸發
實現Promise.all,Promise.race方法
(function (window) { var Promise = function (fn) { var value = null; var callbacks = []; var state = 'pending'; // pending, fulfilled, rejected var promise = this; // 註冊then事件,供resolve後呼叫 promise.then = function (onFulfilled, onRejected) { // 返回promise實現鏈式promise呼叫 return new Promise(function (resolve, reject) { handle({ onFulfilled: onFulfilled || null, onRejected: onRejected || null, resolve: resolve, reject: reject }) }) } promise.catch = function(onRejected) { return promise.then(undefined, onRejected) } function handle (callback) { // 狀態變化前,事件推進佇列裡;狀態一旦變化後不再變動,直接執行結果 if (state === 'pending') { callbacks.push(callback); } else { var cb = state === 'fulfilled' ? callback.onFulfilled : callback.onRejected // then方法沒有傳遞任何引數的情況下,返回結果值 if (!cb) { cb = state === 'fulfilled' ? callback.resolve : callback.reject; cb(value) } else { try { var ret = cb(value); callback.resolve(ret); } catch (e) { callback.reject(e) } } } } function resolve(newValue) { // 狀態一旦改變便不再改變 if (state !== 'pending') return // 假如resolve了一個promise的話(鏈式promise) if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) { var then = newValue.then; if (typeof then === 'function') { // 呼叫第二個promise中的then,遞迴直到不是一個promise值為止 then.call(newValue, resolve, reject); return } } value = newValue; state = 'fulfilled'; execute() } function reject(reason) { // 狀態一旦改變便不再改變 if (state !== 'pending') return state = 'rejected' value = reason execute() } function execute() { // 使用setTimeOut保證resolve一定在then事件註冊後執行 setTimeout(() => { callbacks.forEach(function (callback) { handle(callback); }) }, 0); } fn(resolve, reject); } Promise.all = function (promises) { if (!Array.isArray(promises)) { throw new TypeError('請傳入promise陣列') } return new Promise(function (resolve, reject) { var result = []; var count = promises.length function reslover (index) { return function(value) { resloveAll(index, value) } } function rejecter (reason) { reject(reason) } function resloveAll (index, value) { result[index] = value // 等待全部promise執行完才執行resolve一個陣列 if (--count === 0) { resolve(result) } } promises.forEach(function (promise, index) { promise.then(reslover(index), rejecter) }) }) } Promise.race = function (promises) { if (!Array.isArray(promises)) { throw new TypeError('請傳入promise陣列') } return new Promise(function (resolve, reject) { function reslover (value) { resolve(value) } function rejecter (reason) { reject(reason) } promises.forEach(function (promise, index) { promise.then(reslover, rejecter) }) }) } window.Promise = Promise})(window)/******************************************例項 */function test(i) { return new Promise(function (resolve) { setTimeout(() => { resolve(i); }, 1000); }) }function test2(i) { return new Promise(function (resolve, reject) { setTimeout(() => { if (i % 2) { resolve(i); } else { reject(i); } }, 2000); }) }// 鏈式Promisetest(1).then(test2).then(function (something) { console.log('case1: success!' + something); }).catch(function (something) { console.log('case1: failed!' + something); })// Promise.allPromise.all([test(2), test2(4)]).then(function (something) { console.log('case2: success!' + something); }).catch(function (something) { console.log('case2: failed!' + something) })// Promise.racePromise.race([test(3), test2(5)]).then(function (something) { console.log('case3: success!' + something); }).catch(function (something) { console.log('case3: failed!' + something) })// 多次改變狀態,只有第一次生效function test3 () { return new Promise((resolve, reject) => { setTimeout(() => { resolve('success1') reject('error') resolve('success2') },0) }) } test3().then((res) => { console.log('then: ', res) })// 一旦改變狀態後,多次呼叫then()方法也只會馬上得到Promise返回的值,Promise建構函式不會多次執行function test4 () { return new Promise((resolve, reject) => { setTimeout(() => { resolve('success') }, 1000) }) } const start = Date.now() test4().then((res) => { console.log(res, Date.now() - start) }) test4().then((res) => { console.log(res, Date.now() - start) })
小禮物走一走,來簡書
作者:Eason_Wong
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/755/viewspace-2814875/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Promise知識點Promise
- Promise學習筆記Promise筆記
- Promise 學習筆記Promise筆記
- Promise 物件學習筆記Promise物件筆記
- Promise重要知識點Promise
- 從手寫一個符合Promise/A+規範Promise來深入學習PromisePromise
- promise知識點小結Promise
- Promise的10大知識點!Promise
- 手寫PromisePromise
- 手寫 PromisePromise
- Promise規範以及手寫PromisePromise
- 記錄學習PromisePromise
- promise專題--手寫promise03Promise
- JavaScript學習筆記(一) promise和async/waitJavaScript筆記PromiseAI
- ES6學習筆記(六)【promise,Generator】筆記Promise
- React學習筆記知識點整理React筆記
- 關於Promise知識點都在這裡Promise
- 基於promise /A+規範手寫promisePromise
- 前端面試考點之---手寫Promise前端面試Promise
- ES6語法學習筆記之promise筆記Promise
- 嘗試手寫promisePromise
- 手寫簡易PromisePromise
- 自己動手寫PromisePromise
- 手寫一個PromisePromise
- ES6的Promise知識點總結Promise
- 學習PromisePromise
- JavaScript Promise 學習記錄(一)JavaScriptPromise
- 【筆記】動手學深度學習-預備知識筆記深度學習
- 學習Promise && 簡易實現PromisePromise
- 手寫實現滿足 Promise/A+ 規範的 PromisePromise
- 學習記錄 -- 知識點
- <react學習筆記(5)>知識點回顧(1)React筆記
- Promise/async/await 研究筆記PromiseAI筆記
- 手寫一個自定義PromisePromise
- 手寫 Promise 詳細解讀Promise
- 從頭手寫一個PromisePromise
- 手寫一個自己的PromisePromise
- 基礎知識學習筆記筆記