Promise 的含义
阮一峰老师的《ECMAScript 6 入门》对它的定义:
所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。
简单的看看Promise的使用:
const pm = new Promise((resolve) => {
setTimeout(() => {
resolve(10)
}, 1000)
})
pm.then((res) => {
console.log(res) // 1s后打印10
})
如定义所述,Promise中保存着将来会完成的一件事,完成时就会执行then中的回调函数。
我们要实现的是Promise的简单版myPromise,它能够让下面的代码打印正确的结果:
const mp = new MyPromise((resolve) => {
setTimeout(function() {
resolve(10)
}, 1000)
})
mp
.then((res) => {
console.log(res)
return new MyPromise((resolve) => {
setTimeout(() => {
resolve(res + 10)
}, 1000)
})
})
.then((res) => {
console.log(res)
})
// 1s后打印10
// 2s后打印20
实现简单版myPromise
myPromise主要包括两个功能:
- 异步事件有结果了(
resolve()),立即执行then中的回调函数
- 可以链式调用
第一版:
function MyPromise(fn) {
this.respFn = null
const resolve = (val) => {
this.respFn(val)
}
fn(resolve)
}
MyPromise.prototype.then = function(f) {
this.respFn = f
}
const mp = new MyPromise((resolve) => {
setTimeout(function() {
resolve(10)
}, 1000)
})
mp.then((res) => {
console.log(res) // 1s后打印10
})
这个比较好理解,实例中的respFn属性用来保存then中的回调函数f,当resolve()时会立即去执行该函数。这样就实现了第一个功能。
关于第二个功能就有点绕了,首先then返回一个MyPromise是明确的,但是f不再直接赋值给respFn
第二版:
function MyPromise(fn) {
this.respFn = null
const resolve = (val) => {
this.respFn(val)
}
fn(resolve)
}
MyPromise.prototype.then = function(f) {
return new MyPromise((resolve) => {
this.respFn = (val) => {
const fv = f(val)
if (fv instanceof MyPromise) {
fv.then(resolve)
} else {
resolve(fv)
}
}
})
}
const mp = new MyPromise((resolve) => {
setTimeout(function() {
resolve(10)
}, 1000)
})
mp
.then((res) => {
console.log(res)
return new MyPromise((resolve) => {
setTimeout(() => {
resolve(res + 10)
}, 1000)
})
})
.then((res) => {
console.log(res)
})
// 1s后打印10
// 2s后打印20
看看以上代码,respFn被赋值为了一个新函数,而then中的回调函数f则是在新函数中去调用。想一想,第二个then的回调函数的执行时机是由第一个then方法返回的MyPromise决定的,而MyPromise什么时候resolve()又是函数f的返回值决定的,所以,我们需要一个新函数作为中间者,在新函数中拿到f的返回值再决定resolve()的时机。从if else这段代码可以看出来,当f的返回值不是MyPromise时会直接resolve(),否则会等f返回的MyPromise解决了才会resolve()。
最后在处理一下MyPromise中不做异步而是直接resolve()和respFn不是函数的情况
最终版:
function MyPromise(fn) {
this.respFn = null
const resolve = (val) => {
queueMicrotask(() => {
if (this.respFn instanceof Function) {
this.respFn(val)
}
})
}
fn(resolve)
}
MyPromise.prototype.then = function(f) {
return new MyPromise((resolve) => {
this.respFn = (val) => {
const fv = f(val)
if (fv instanceof MyPromise) {
fv.then(resolve)
} else {
resolve(fv)
}
}
})
}
你品,你细细的品
Promise 的含义
阮一峰老师的《ECMAScript 6 入门》对它的定义:
简单的看看Promise的使用:
如定义所述,Promise中保存着将来会完成的一件事,完成时就会执行then中的回调函数。
我们要实现的是Promise的简单版myPromise,它能够让下面的代码打印正确的结果:
实现简单版myPromise
myPromise主要包括两个功能:
resolve()),立即执行then中的回调函数第一版:
这个比较好理解,实例中的
respFn属性用来保存then中的回调函数f,当resolve()时会立即去执行该函数。这样就实现了第一个功能。关于第二个功能就有点绕了,首先
then返回一个MyPromise是明确的,但是f不再直接赋值给respFn第二版:
看看以上代码,
respFn被赋值为了一个新函数,而then中的回调函数f则是在新函数中去调用。想一想,第二个then的回调函数的执行时机是由第一个then方法返回的MyPromise决定的,而MyPromise什么时候resolve()又是函数f的返回值决定的,所以,我们需要一个新函数作为中间者,在新函数中拿到f的返回值再决定resolve()的时机。从if else这段代码可以看出来,当f的返回值不是MyPromise时会直接resolve(),否则会等f返回的MyPromise解决了才会resolve()。最后在处理一下
MyPromise中不做异步而是直接resolve()和respFn不是函数的情况最终版:
你品,你细细的品