我们接着上面 接着写。
// promise.js
const STATUS = {
PENDING: 'PENDING',
FULFILLED: 'FULFILLED',
REJECTED: 'REJECTED'
}
class Promise {
constructor(executor) {
this.status = STATUS.PENDING
this.value = undefined
this.reason = undefined
this.onResolvedCallBacks = [] // 存放成功时的回调
this.onRejectedCallBacks = [] // 存放失败时的回调
const resolve = val => {
if (this.status == STATUS.PENDING) {
this.status = STATUS.FULFILLED
this.value = val
// 发布
this.onResolvedCallBacks.forEach(fn => fn())
}
}
const reject = reason => {
if (this.status == STATUS.PENDING) {
this.status = STATUS.REJECTED
this.reason = reason
// 发布
this.onRejectedCallBacks.forEach(fn => fn())
}
}
try {
executor(resolve, reject)
} catch (e) {
// 失败走失败的逻辑处理
reject(e)
}
}
then(onfulfilled, onRejected) {
if (this.status == STATUS.FULFILLED) {
onfulfilled(this.value)
}
if (this.status == STATUS.REJECTED) {
onRejected(this.reason)
}
// 订阅
if (this.status == STATUS.PENDING) {
this.onResolvedCallBacks.push(() => {
onfulfilled(this.value)
})
this.onRejectedCallBacks.push(() => {
onRejected(this.reason)
})
}
}
}
module.exports = Promise
// index.js
const Promise = require('./promise.js')
let p = new Promise((resolve, reject) => {
// throw new Error('aa')
setTimeout(() => {
resolve('成功了')
}, 1000)
})
p.then(
data => {
console.log('success', data)
},
reason => {
console.log('fail', reason)
}
)
p.then(
data => {
console.log('success', data)
},
reason => {
console.log('fail', reason)
}
)
console.log(22)
这里我们就先打印出 22
, 接着过1秒之后会打印出两个 success 成功了
最终结果:
22
success 成功了
success 成功了
其实大家看下这里 ,和上一篇(2. 手写Promise - 雏形)只是增加了 几行代码而已 。
运用 发布订阅模式。把成功和失败存放在一起 ,之后一起发布通知 。
Promise 中的链式调用
- 如果
then
方法中,(成功或者失败),返回的不是一个promise
,会将这个值传递给外层的下一个.then
的成功结果 - 如果执行
.then
方法中的方法出错了 ,抛出异常,会走到当前的失败当中。 - 如果返回的是一个
promise
, 会用这个promise
的结果作为 下一次的成功或者失败 -
then
方法每次调用都会返回一个新的promise
。
- 出错走失败
-
promise
失败也会走失败 - 其他的都会走成功
-
catch
其实就是then
的别名 ,没有成功 只有失败(找最近的优先处理,处理不了 就找下一层)
const STATUS = {
PENDING: 'PENDING',
FUFILLED: 'FUFILLED',
REJECTED: 'REJECTED'
}
function resolvePromise(x, promise2, resolve, reject) {
if (promise2 == x) {
return reject(new TypeError('出错了'))
}
if ((typeof x === 'object' && x !== null) || typeof x === 'function') {
let called
try {
let then = x.then
if (typeof then == 'function') {
then.call(
x,
function(y) {
if (called) return
called = true
resolvePromise(y, promise2, resolve, reject)
},
function(r) {
if (called) return
called = true
reject(r)
}
)
} else {
resolve(x)
}
} catch (e) {
if (called) return
called = true
reject(e)
}
} else {
resolve(x)
}
}
class Promise {
constructor(executor) {
this.status = STATUS.PENDING
this.value = undefined
this.reason = undefined
this.onResolvedCallbacks = [] // 存放成功的回调的
this.onRejectedCallbacks = [] // 存放失败的回调的
const resolve = val => {
if (val instanceof Promise) {
// 是promise 就继续递归解析
return val.then(resolve, reject)
}
if (this.status == STATUS.PENDING) {
this.status = STATUS.FUFILLED
this.value = val
// 发布
this.onResolvedCallbacks.forEach(fn => fn())
}
}
const reject = reason => {
if (this.status == STATUS.PENDING) {
this.status = STATUS.REJECTED
this.reason = reason
// 腹部
this.onRejectedCallbacks.forEach(fn => fn())
}
}
try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : x => x
onRejected =
typeof onRejected === 'function'
? onRejected
: err => {
throw err
}
let promise2 = new Promise((resolve, reject) => {
if (this.status === STATUS.FUFILLED) {
setTimeout(() => {
try {
let x = onFulfilled(this.value)
resolvePromise(x, promise2, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
}
if (this.status === STATUS.REJECTED) {
setTimeout(() => {
try {
let x = onRejected(this.reason)
resolvePromise(x, promise2, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
}
if (this.status === STATUS.PENDING) {
this.onResolvedCallbacks.push(() => {
setTimeout(() => {
try {
let x = onFulfilled(this.value)
resolvePromise(x, promise2, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
})
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
let x = onRejected(this.reason)
resolvePromise(x, promise2, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
})
}
})
return promise2
}
catch(err) {
return this.then(null, err)
}
static resolve(val) {
return new Promise((resolve, reject) => {
resolve(val)
})
}
static reject(reason) {
// 失败的promise
return new Promise((resolve, reject) => {
reject(reason)
})
}
}
// 测试时会调用此方法 Promise.finally resolve reject catch all
Promise.defer = Promise.deferred = function() {
let dfd = {}
dfd.promise = new Promise((resolve, reject) => {
dfd.resolve = resolve
dfd.reject = reject
})
return dfd
}
// npm install promises-aplus-tests -g
module.exports = Promise
测试 promise 的结果
到此我们就完成了 手写
promise
了。接下来我们写
promise
里面的一些方法 。
- promise.finally
- promise.all
- promise.race
.....
更多知识点 请关注:笔墨是小舟