promise
有幾個重要的概念,只要弄明白這幾點,基本上就能夠實現大體的框架了git
promise
中有三種狀態,pending
,fulfilled
,rejected
promise
一旦resolve
,他的狀態立刻變成fulfilled
,再執行本身的onResolve
函數後,resolve
下一個promise
,依次類推then
接收onResolve
和onReject
做爲參數,若是這兩個函數返回值爲promise
,則要等待這個promise
,若是返回值不是promise
,則將這個返回值傳遞給下一個promise
then
會返回一個promise
對象首先寫一些主要的測試代碼github
<!-- 異步 -->
new Promise((resolve, reject) => {
setTimeout(() => {
console.log('executor')
resolve(1)
}, 1000)
})
.then(value => {
console.log('then1', value)
return 2
})
.then(value => {
console.log('then2', value)
})
複製代碼
<!-- 同步 -->
new Promise((resolve, reject) => {
console.log('executor')
resolve(1)
})
.then(value => {
console.log('then1', value)
return 2
})
.then(value => {
console.log('then2', value)
})
複製代碼
<!-- 同步 異步 嵌套promise -->
new Promise((resolve, reject) => {
console.log('外部promise')
resolve(1)
})
.then(value => {
console.log('外部then1', value)
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('內部promise')
resolve(2)
}, 1000)
})
.then(value => {
console.log('內部then1', value);
return 3
})
.then(value => {
console.log('內部then2', value);
return 4
})
})
.then(value => {
console.log('外部then2', value);
})
複製代碼
第一步確定是實現new Promise(executor)
的寫法,調用promise
的構造函數,傳入一個參數爲resolve
和reject
的函數,並當即執行promise
constructor(executor) {
this.state = "pending";
this.value = undefined;
this.reason = undefined;
this.resolveCallbacks = []
this.nextPromise = undefined
if (executor && typeof executor === "function") {
executor(this.resolve.bind(this), this.reject.bind(this));
}
}
複製代碼
resolve
接受一個value
,而且改變promise的狀態resolve
改變狀態後,執行本身的onResolve
回調promise
的resolve
,其中還要判斷onResolve
返回的是否爲promise
對象,是的話要等待這個promiseresolve(value) {
if (this.state === "pending") {
this.state = "fulfilled"
this.value = value
if (this.resolveCallbacks.length) {
// 調用then中註冊的onResolve回調
while(this.resolveCallbacks.length) {
const onResolve = this.resolveCallbacks.pop()
const result = onResolve(value)
if (result instance of Promise) {
// 若是是promise對象,調用這個promise的then
result.then(v => {
this.nextPromise && this.nextPromise.resolve(value)
})
} else {
this.nextPromise && this.nextPromise.resolve(value)
}
}
} else {
// 沒有的話就執行下一個promise的回調
this.nextPromise && this.nextPromise.resolve(value)
}
}
}
複製代碼
fulfilled
,這個時候就立刻執行onResolve
回調pending
,這個時候要把onResolve
存起來then
一直會返回一個promise
對象then(onResolve, onReject) {
let promise = new Promise()
if (this.state === "fulfilled") {
// 若是onResolve返回的不是一個promise對象,就返回一個立刻resolve的promise
// 若是onResolve返回的是promise,就在該promise對象的then裏面resolve
promise = new Promise((resolve, reject) => {
if (onResolve && typeof onResolve === "function") {
const result = onResolve(this.value)
if (result instanceof Promise) {
result.then(value => {
resolve(value)
})
} else {
resolve(result)
}
} else {
resolve(this.value)
}
})
} else if (this.state === "pending") {
if (onResolve && typeof onResolve === "function") {
this.resolveCallbacks.push(onResolve)
}
}
this.nextPromise = promise
return promise
}
複製代碼
then
和catch
的回調必須放到微任務隊列執行的(window.queueMicrotask
或者proess.nextTick
),注意不是setTimeout
try catch
和 reject
,注意catch
和reject
都是異常捕獲,而且發生異常的時候catch
和reject
會按照聲明順序,只執行一個最早聲明的一個resolve
和reject
eventloop
,microTask
,macroTask
,promise
的執行機制的理解都清晰不少了