Promise用法
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('success')
}, 1000)
}).then(res => {
console.log(res) // 输出success
})
从代码里可以看出Promise
构造函数接受一个匿名函数,匿名函数有两个参数,这两个参数也是函数。
打印出来的结果如下图:
可以观察到在resolve
回调之前,Promise
有一个pending
状态;查看文档我们知道Promise
有三个状态:pending
(默认状态:等待),fulfilled
(已成功),rejected
(已拒绝)。
现在我们来尝试写一个自己的Promise
手写Promise
1、创建构造函数MyPromise
,参数为一个函数fn
2、fn有两个参数,分别是成功(resolve)和拒绝(reject)的回调函数
3、resolve函数保存成功的值,reject函数保存失败原因
4、MyPromise
实例原型需提供一个then函数供实例调用
5、then函数参数为一个匿名函数,该函数必须在resolve或reject之后执行
function MyPromise(fn) {
// 默认状态为 pending
this.state = 'pending'
let self = this
function resolve(value) {
// 保存成功的值并将状态设为 resolved
self.value = value
self.state = 'resolved'
}
function reject(reason) {
self.reason = reason
self.state = 'rejected'
}
fn(resolve, reject);
}
MyPromise.prototype.then = function(onFinish) {
if (this.state === 'resolved') {
onFinish(this.value)
}
if (this.state === 'rejected') {
onFinish(this.reason)
}
}
写到这里我们写一段代码测试一下
var p = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve(1)
}, 1000)
})
p.then(res => {
console.log(res)
})
发现没有输出打印结果,原因是setTimeout为异步代码,then函数先于resolve和reject函数执行。
为了确保then函数里面的函数在resolve和reject之后执行,我们可以将其存储起来,resolve和reject执行之后再执行该函数。
function MyPromise(fn) {
// 默认状态为 pending
this.state = 'pending'
this.resolveStack = []
this.rejectStack = []
let self = this
function resolve(value) {
// 保存成功的值并将状态设为 resolved
if (self.state === 'pending') {
self.value = value
self.state = 'resolved'
self.resolveStack.forEach(cb => {
cb(self.value)
})
}
}
function reject(reason) {
if (self.state === 'pending') {
self.reason = reason
self.state = 'rejected'
self.rejectStack.forEach(cb => {
cb(self.reason)
})
}
}
fn(resolve, reject);
}
MyPromise.prototype.then = function(onFinish) {
if (this.state === 'pending') {
this.resolveStack.push(onFinish)
this.rejectStack.push(onFinish)
}
if (this.state === 'resolved') {
onFinish(this.value)
}
if (this.state === 'rejected') {
onFinish(this.reason)
}
}
var p = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve(1)
}, 1000)
})
p.then(res => {
console.log(res)
})
到这里,一个Promise就差不多完成了。。。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。