// 手写 Promise,深入理解 node.js 事件循环与异步机制
class SPromise {
static STATUS_PENDING = -1
static STATUS_RESOLVED = 0
static STATUS_REJECTED = 1
constructor(callback) {
if (typeof callback !== 'function') {
throw new TypeError('Promise resolver is not a function')
}
// 定义 Promise 当前状态
this.status = SPromise.STATUS_PENDING
// 定义 Promise 值
this.value = null
// 定义 resolve/reject 时的承诺兑现回调
this.onFulfill = [[], []]
// Promise 创建即运行
callback(this._genFulfiller(SPromise.STATUS_RESOLVED),
this._genFulfiller(SPromise.STATUS_REJECTED))
}
then(onResolve, onReject) {
return new SPromise((resolve, reject) => {
function genCallback(fullfil, onFulfill) {
return value => {
if (typeof onFulfill === 'function') {
let result = onFulfill(value)
if (result instanceof SPromise) {
// 若当前兑现回调仍返回 promise,则将它的兑现结果用来兑现当前 promise,由此可形成串联有序的 then 异步链
result.then(resolve, reject)
} else {
fullfil(result)
}
} else {
fullfil(value) // 当前 then 中无处理函数,直接将值传给下个 Promise 的 then
}
}
}
this.onFulfill[SPromise.STATUS_RESOLVED].push(genCallback(resolve, onResolve))
this.onFulfill[SPromise.STATUS_REJECTED].push(genCallback(reject, onReject))
})
}
_genFulfiller(status) {
return value => {
process.nextTick(() => { // 可以用 setImmediate,process.nextTick,setTimeout 等实验
if (this.status !== SPromise.STATUS_PENDING) {
return
}
this.status = status
this.value = value
let handler
while (handler = this.onFulfill[status].shift()) {
handler(this.value)
}
})
}
}
}
测试:
function test1() {
let text = '界世,好你'
return new SPromise((resolve, reject) => {
setTimeout(() => {
resolve(text.split(''))
},1000)
}).then((value) => { // 异步回调
console.log('[then1]', value)
return new SPromise((resolve, reject) => {
setTimeout(() => {
resolve(value.reverse())
})
})
}).then((value) => { // 同步回调
console.log('[then2]', value)
return value.join('')
}).then((value) => {
console.log('[then3]', value)
})
}
function test2() {
const https = require('https')
function get(keyword) {
return new SPromise((resolve, reject) => {
https.get('https://suggest.taobao.com/sug?code=utf-8&q=' + keyword, response => {
let data = ''
response.on('data', chunk => {
data += chunk
});
response.on('end', () => {
resolve(data)
});
}).on('error', err => {
reject(err.message)
})
})
}
get('华为')
.then((value) => { // 异步回调
console.log('[then1]', value)
return get('苹果')
}).then((value) => { // 同步回调
console.log('[then2]', value)
return JSON.parse(value)
}).then((value) => {
console.log('[then3]', value['result'])
})
}
test1()
.then(() => {
console.log('---------------------------')
test2()
})
输出:
[then1] [ '界', '世', ',', '好', '你' ]
[then2] [ '你', '好', ',', '世', '界' ]
[then3] 你好,世界
---------------------------
[then1]
{"result":[["华为手机","92286.56965703903"],["华为手表","27807.92949657869"],["华为平板","22296.07215536921"],["华为手机壳","408213.7418392727"],[" 华为耳机","127327.02135785471"],["华为mate40pro 手机壳","93927.45274956428"],["华为p40pro手机壳","82318.16788240494"],["华为p50pro手机壳","48962.31444975183"],["华为蓝牙耳机","129108.50988561928"],["华为p30手机壳","73065.21080485791"]],"shop":"华为"}
[then2]
{"result":[["苹果13","283281.39529907546"],["苹果13手机壳","324043.6103134092"],["苹果手机壳","560190.7401519603"],["苹果手机","558248.7950667278"],["苹果12手机壳","357129.2587940854"],["苹果11手机壳","342352.2528573405"],["苹果耳机","143633.09875067897"],["苹果12","407013.10131413804"],["苹果数据线","664766.3167561188"],["苹果13promax手机壳","294009.9901284209"]],"shop":"苹果"}
[then3] [
[ '苹果13', '283281.39529907546' ],
[ '苹果13手机壳', '324043.6103134092' ],
[ '苹果手机壳', '560190.7401519603' ],
[ '苹果手机', '558248.7950667278' ],
[ '苹果12手机壳', '357129.2587940854' ],
[ '苹果11手机壳', '342352.2528573405' ],
[ '苹果耳机', '143633.09875067897' ],
[ '苹果12', '407013.10131413804' ],
[ '苹果数据线', '664766.3167561188' ],
[ '苹果13promax手机壳', '294009.9901284209' ]
]