简单的promise链式调用代码解释
摘要:简单的promise链式调用代码解释
promise的很简单的一个实现
// 三种状态
const PENDING = Symbol()
const FULFILLED = Symbol()
const REJECTED = Symbol()
function Promisee(fn) {
// fn 必须是函数
if (typeof fn !== 'function') {
throw new Error('fn must be a function!')
}
let state = PENDING // 初始状态是 PENDING
let value = null // 返回值
let handler = {}
function fulfill (result) {
state = FULFILLED
value = result
next(handler)
}
// 完成时调用的方法,这里做了容错
function resolve (result) {
try {
fulfill(result)
} catch (err) {
reject(err)
}
}
// 拒绝时调用的方法
function reject (error) {
state = REJECTED
value = error
next(handler)
}
function next({ onFulfill, onReject }) {
switch (state) {
case FULFILLED:
onFulfill && onFulfill(value)
break
case REJECTED:
onReject && onReject(value)
break
case PENDING:
handler = { onFulfill, onReject }
}
}
this.then = function (onFulfill, onReject) {
return new Promisee((resolve, reject) => {
next({
onFulfill: val => {
resolve(onFulfill(val))
},
onReject: err => {
reject(onReject(err))
}
})
})
}
fn(resolve, reject)
}
let p =new Promisee((resolve,reject) => {reject('hello');})
//let p =new Promisee((resolve,reject) => {setTimeout(() => reject('hello'),0)});
p.then(console.log.bind(null,'over'),console.error.bind(null,'error')).then(console.log.bind(null,'over'),console.error.bind(null,'error'))
执行顺序
异步调用
fn1 -> then -> resolve/reject -> then 回调
同步调用
fn1 -> resolve/reject -> then -> then 回调
异步调用详细解释
let p =new Promisee((resolve,reject) => {setTimeout(() => resolve('hello'),0)});
p.then(console.log.bind(null,'over'),console.error.bind(null,'error')).then(console.log.bind(null,'over'),console.error.bind(null,'error'));
//为了方便解释 上面的代码可以看成
let p1 =new Promisee((resolve,reject) => {setTimeout(() => resolve('hello'),0)});
let p2 = p1.then(console.log.bind(null,'over'),console.error.bind(null,'error'));
let p3 = p2.then(console.log.bind(null,'over'),console.error.bind(null,'error'));
1.先new Promisee一个对象p1
2.p1将传入的(resolve,reject) => {setTimeout(() => reject('hello'),0)}当作fn(resolve, reject)
3.执行setTimeout将() => reject('hello')放入宏任务队列
4.执行p1.then(console.log.bind(null,'over'),console.error.bind(null,'error'))
5.p1.then返回一个对象p2
6.p1.then返回的对象p2开始将
(resolve, reject) => {
next({
onFulfill: val => {
resolve(onFulfill(val))
},
onReject: err => {
reject(onReject(err))
}
})
}
当作fn(resolve, reject)执行
7.注意
(resolve, reject) => {
next({
onFulfill: val => {
resolve(onFulfill(val))
},
onReject: err => {
reject(onReject(err))
}
})
}
的执行环境是p1,也就是next会在p1这个对象下执行。而其中的resovle则会在p2对象执行。
详情见:https://www.keepnight.com/archives/145/
8.因为p1的state为PENDING,所以会把next函数里面的
{
onFulfill: val => {
resolve(onFulfill(val))
},
onReject: err => {
reject(onReject(err))
}
}
这个对象放入p1对象的handle里。画重点:resolve和reject是p2对象中的。
9.得到p2对象后,p2调用p2.then(console.log.bind(null,'over'),console.error.bind(null,'error'))返回一个对象p3
10.p2.then返回的对象p3开始将
(resolve, reject) => {
next({
onFulfill: val => {
resolve(onFulfill(val))
},
onReject: err => {
reject(onReject(err))
}
})
}
当作fn(resolve, reject)执行
11.因为p2的state为PENDING,所以会把next函数里面的
{
onFulfill: val => {
resolve(onFulfill(val))
},
onReject: err => {
reject(onReject(err))
}
}
这个对象放入p2对象的handle里。画重点:resolve和reject是p3对象中的。
12.主线程执行完毕,开始执行setTimeout宏任务。() => resolve('hello')函数执行改变p1中的state为FULFILLED,接着调用p1的resolve方法next(handler),而handler里面放的是
{
onFulfill: val => {
resolve(onFulfill(val))
},
onReject: err => {
reject(onReject(err))
}
}
就相当于先执行onFulfill(val)(或者说p1.then中的第一个回调函数),然后调用来自p2的resolve方法,改变p2的state为FULFILLED。接着调用来自p2的resolve方法中的next(handler),而handler里面放的是
{
onFulfill: val => {
resolve(onFulfill(val))
},
onReject: err => {
reject(onReject(err))
}
}
就相当于先执行onFulfill(val)(或者说p2.then中的第一个回调函数),然后调用来自p3的resolve方法,改变p3的state为FULFILLED.
同步调用详细解释
let p =new Promisee((resolve,reject) => {resolve('hello');})
p.then(console.log.bind(null,'over'),console.error.bind(null,'error')).then(console.log.bind(null,'over'),console.error.bind(null,'error'));
//为了方便解释 上面的代码可以看成
let p1 =new Promisee((resolve,reject) => {resolve('hello');});
let p2 = p1.then(console.log.bind(null,'over'),console.error.bind(null,'error'));
let p3 = p2.then(console.log.bind(null,'over'),console.error.bind(null,'error'));
1.先new Promisee一个对象p1
2.p1将传入的(resolve,reject) => {reject('hello');}当作fn(resolve, reject)
3.fn(resolve, reject)直接执行将p1中的state设定为FULFILLED,并将value赋值为'hello'
4.p1.then返回一个对象p2
5.p1.then返回的对象p2开始将
(resolve, reject) => {
next({
onFulfill: val => {
resolve(onFulfill(val))
},
onReject: err => {
reject(onReject(err))
}
})
}
当作fn(resolve, reject)执行,next会在p1这个对象下执行,其中的resovle则会在p2对象执行。
6.因为p1中的state为FULFILLED,value赋值为'hello',所以调用
onFulfill: val => {
resolve(onFulfill(val))
},
先执行p1.then中的第一个回调函数,然后将这个函数的返回值传递给p2对象,resolve将p2对象的state设置为FULFILLED,p2对象的vaule设置为onFulfill(val)的返回值
7.p2对象调用p2.then返回一个对象p3
8.p2.then返回的对象p3开始将
(resolve, reject) => {
next({
onFulfill: val => {
resolve(onFulfill(val))
},
onReject: err => {
reject(onReject(err))
}
})
}
当作fn(resolve, reject)执行,next会在p2这个对象下执行,其中的resovle则会在p3对象执行。
6.因为p2中的state为FULFILLED,value赋值为undefined,所以调用
onFulfill: val => {
resolve(onFulfill(val))
},
先执行p2.then中的第一个回调函数,然后将这个函数的返回值传递给p3对象,resolve将p3对象的state设置为FULFILLED,p3对象的vaule设置为onFulfill(val)的返回值。
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。