目录
- 从简单使用着手
- 添加异步处理和实例多次调用then
- 链式调用的实现
温习promise的简单使用
先来看一下promise使用的一个小例子:
let p = new Promise(function (resolve, reject) {
console.log('start')
resolve('data1')
})
p.then(
(v) => {
console.log('success: ' + v)
},
(v) => {
console.log('error: ' + v)
}
)
console.log('end')
复制代码
运行结果如下:
针对这个例子做以下几点说明,也是需要直接记住的,因为这就好比是解答数学题的公式一样,开始一定要记牢。
- Promise是构造函数,new 出来的实例有then方法。
- new Promise时,传递一个参数,这个参数是函数,又被称为执行器函数(executor), 并执行器会被立即调用,也就是上面结果中start最先输出的原因。
- executor是函数,它接受两个参数 resolve reject ,同时这两个参数也是函数。
- new Promise后的实例具有状态, 默认状态是等待,当执行器调用resolve后, 实例状态为成功状态, 当执行器调用reject后,实例状态为失败状态。
- promise翻译过来是承诺的意思,实例的状态一经改变,不能再次修改,不能成功再变失败,或者反过来也不行。
- 每一个promise实例都有方法 then ,then中有两个参数 ,这两个参数也都是函数,当执行器调用resolve后,then中第一个参数函数会执行。当执行器调用reject后,then中第二个参数函数会执行。
那么就目前的这些功能,或者说规则,来着手写一下MyPromise构造函数吧。
1 构造函数的参数,在new 的过程中会立即执行
// 因为会立即执行这个执行器函数
function MyPromise(executor){
executor(resolve, reject)
}
复制代码
2 new出来的实例具有then方法
MyPromise.prototype.then = function(onFulfilled, onRejected){
}
复制代码
3 new出来的实例具有默认状态,执行器执行resolve或者reject,修改状态
function MyPromise(executor){
let self = this
self.status = 'pending' // 默认promise状态是pending
function resolve(value){
self.status = 'resolved' // 成功状态
}
function reject(reason){
self.status = 'rejected' //失败状态
}
executor(resolve, reject)
}
复制代码
4 当执行器调用resolve后,then中第一个参数函数会执行,当执行器调用reject后,then中第二个参数函数会执行
MyPromise.prototype.then = function(onFulfilled, onRejected){
let self = this
if(self.status === 'resolved'){
onFulfilled()
}
if(self.status === 'rejected'){
onRejected()
}
}
复制代码
5 保证状态一旦变更不能再次改变
function Promise(executor){
let self = this
self.status = 'pending' // 默认promise状态是pending
function resolve(value){
if(self.status === 'pending'){ //保证状态一旦变更,不能再次修改
self.value = value
self.status = 'resolved' // 成功状态
}
}
function reject(reason){
if(self.status === 'pending'){
self.reason = reason
self.status = 'rejected' //失败状态
}
}
executor(resolve, reject)
}
复制代码
6 执行器执行resolve方法传的值,传递给then中第一个参数函数中
function MyPromise(executor){
let self = this
self.value = undefined
self.reason = undefined
self.status = 'pending' // 默认promise状态是pending
function resolve(value){
if(self.status === 'pending'){ //保证状态一旦变更,不能再次修改
self.value = value
self.status = 'resolved' // 成功状态
}
}
function reject(reason){
if(self.status === 'pending'){
self.reason = reason
self.status = 'rejected' //失败状态
}
}
executor(resolve, reject) // 因为会立即执行这个执行器函数
}
MyPromise.prototype.then = function(onFulfilled, onRejected){
let self = this
if(self.status === 'resolved'){
onFulfilled(self.value)
}
if(self.status === 'rejected'){
onRejected(self.reason)
}
}
复制代码
尝试使用一下这个 MyPromise :
let p = new MyPromise(function (resolve, reject) {
console.log('start')
resolve('data2')
})
p.then(
(v) => {
console.log('success ' + v)
},
(v) => {
console.log('error ' + v)
}
)
console.log('end')
复制代码
运行结果如下:
结果看似对了,不过和原生的promise还是有不同的,就是success那条语句的打印顺序,不要急,MyPromise 还没有写完。
添加异步处理逻辑
还是看原生promise的使用小例子
let p = new Promise(function (resolve, reject) {
console.log('start')
setTimeout(function(){
resolve('data1')
},2000)
})
p.then(
(v) => {
console.log('success: ' + v)
},
(v) => {
console.log('error: ' + v)
}
)
console.log('end')
复制代码
运行结果如下
实例多次调用then方法情况(注意不是链式调用)
let p = new Promise(function (resolve, reject) {
console.log('start')
setTimeout(function(){
resolve('data1')
},2000)
})
p.then(
(v) => {
console.log('success: ' + v)
},
(v) => {
console.log('error: ' + v)
}
)
p.then(
(v) => {
console.log('success: ' + v)
},
(v) => {
console.log('error: ' + v)
}
)
console.log('end')
复制代码
运行结果如下
那么针对这种异步的情况和实例p多次调用then方法,我们上述MyPromise该如何修改呢?