先看一下這一次要講的涉及到的promise的基礎用法php
let pms = new Promise((resolve, reject) => { setTimeout(() => { if (parseInt(Math.random()*10) > 5) { console.log('隨機數大於5,算任務成功了') resolve('還能夠傳參哦') } else { console.log('隨機數< 5,算任務失敗了') reject('還能夠傳參哦< 5') } }, 1500) }) pms.then((value) => { console.log('success', value) }, (reason) => { console.log('fail', reason) })
1.5s後若是隨機的數大於5走resolve()輸出:
'隨機數大於5,算任務成功了', 'success',
小於5走reject(),輸出:
'隨機數< 5,算任務失敗了', 'fail'. 數組
咱們先寫promise的這兩個功能:
構造函數的參數接受一個函數。
函數在被調用的時候,會被promise傳入兩個參數resolve跟reject。promise
function Promise(executor){ executor(resolve, reject) function resolve(){} function reject(){} }
能夠看到一new Promise就會執行傳入的函數,也就是咱們起名爲executor的函數.
你們確定納悶兒爲啥要在executor裏調用resolve或者reject,咱們裏先上代碼:dom
function Promise(executor) { let self = this; self.value = undefined; self.reason = undefined; self.status = 'pending'; self.onFulFilledCallbacks = []; self.onRejectedCallbacks = []; function resolve(value) { if (self.status === 'pending') { self.value = value; self.status = 'resolved' self.onFulFilledCallbacks.forEach(onFulFilled => { onFulFilled(self.value) }); } } function reject(reason) { if (self.status === 'pending') { self.reason = reason; self.status = 'rejected'; self.onRejectedCallbacks.forEach(onRejected => { onRejected(self.reason) }); } } try { executor(resolve, reject); } catch (error) { reject(error) } } Promise.prototype.then = function (onFulFilled, onRejected) { if (this.status === 'pending') { this.onFulFilledCallbacks.push(() => { onFulFilled(this.value) }); this.onRejectedCallbacks.push(() => { onRejected(this.reason) }) } else if (this.status === 'resolved') { onFulFilled(this.value); } else if (this.status === 'rejected') { onRejected(this.reason); } }
promise的三種狀:等待pending,成功resolve,失敗rejected.(說直接一點就是用來記錄resolve或者reject是否已經調用,也就是常說的那個executor任務執行成功了仍是失敗了)函數
這一次咱們新增了兩個數組onFulFilledCallbacks、onRejectedCallbacks用來保存調用then的時候傳的兩個回調函數(固然若是在調用then的時候已經resolve或reject,那就直接執行傳入的函數,不用保存了),因此executor裏必定會調用resolve或者reject中的一個,由於一個函數的執行不是this
(邏輯上成功)
就是prototype
(邏輯上失敗)
.對應咱們寫的例子就是隨機數不是大於5就是小於5. code
executor任務成功了確定有成功後的結果,失敗了咱們確定也拿到失敗的緣由。因此value與reason一個是用來保存成功的結果,一個是用來保存失敗的緣由。blog
ps:onFulFilledCallbacks、onRejectedCallbacks定爲數組的緣由是爲了這個功能:get
pms.then((value) => { console.log('success1', value) }, (reason) => { console.log('fail1', reason) }) pms.then((value) => { console.log('success2', value) }, (reason) => { console.log('fail2', reason) }) //then屢次得把這些函數給存起來,到時候成功或者失敗的時候,遍歷依次執行~
下一張咱們進入Promise最迷人的鏈式調用.
最最最通俗易懂的promise手寫系列(二)- 鏈式調用
轉載於猿2048:➝《最最最通俗易懂的promise手寫系列(一)》