这是我参与8月更文挑战的第二天,活动详情查看:8月更文挑战
前言
本文将成为promise这个大关卡的通关秘籍。目前,只是分享一些关于promise的总结和手写promise。后续将通过更多的面试题来完善该文。
正文
Promise的这些问题你都知道吗?
promise的定义
- promise是异步编程的一种解决方案
promise的用法
- promise是一个构造函数 , 通过new生成promise实例
- Promise接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。
- resolve函数作用:
- 将Promise对象的状态从 pending 变为 resolved
- 在异步操作成功时调用
- 将异步操作的结果,作为参数传递出去
- reject函数作用:
- 将Promise对象的状态从 pending 变为 reject
- 在异步操作失败时调用
- 并将异步操作报出的错误,作为参数传递出去
- resolve函数作用:
promise的特点
- 对象的状态不会受外界影响.peromise对象代表一个异步操作,它有三种状态,只有异步操作的结果,可以决定是哪一种状态,其他都无法影响
- 一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。
promise的优点 (相比于回调地狱,更多的是优化写法,主要是写法上的优化)
- 可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。
- Promise对象提供统一的接口,使得控制异步操作更加容易。
promise的缺点
- 无法取消Promise,一旦新建它就会立即执行,无法中途取消。
- 如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。
- 当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。
如何实现一个简易版Promise
// 手撸一个promise
(function (window) {
function myPromise(execotor) {
let self = this
self.status = 'pending'
self.data = undefined // 存储resolve的结果
self.callbacks = [] // {onResolved => {}, onRejected => {}}
function resolve(value) {
if (self.status !== 'pending') {
return
}
// 将状态改变成为resolved
self.status = 'resolved'
// 存值
self.data = value
// 如果有待执行的callback函数,立即异步执行它
if (self.callbacks.length > 0) {
setTimeout(() => {
self.callbacks.forEach(callbackObj => {
callbackObj.onResolved(value)
})
}, 0)
}
}
function reject(value) {
if (self.status !== 'pending') {
return
}
// 将状态改变成为resolved
self.status = 'resolved'
// 存值
self.data = value
// 如果有待执行的callback函数,立即异步执行它
if (self.callbacks.length > 0) {
setTimeout(() => {
self.callbacks.forEach(callbackObj => {
callbackObj.onResolved(value)
})
}, 0)
}
}
try {
execotor(resolve, reject)
} catch (error) {
reject(error)
}
}
// promise 原型挂载各种方法
myPromise.prototype.then = function(onResolved, onRejected) {
// onResolved onRejected 存到数组
// this.callbacks.push({ onResolved, onRejected })
let self = this
return new myPromise((resolve, reject) => {
if (self.status === 'pending') {
self.callbacks.push({
onResolved() { onResolved(self.data) },
onRejected() { onRejected(self.data) }
})
} else if (self.status === 'resolved') {
setTimeout(() => {
const result = onResolved(self.data)
if (result instanceof myPromise) {
result.then(
value => { resolve(value) },
reason => { reject(reason) }
)
} else {
resolve(result)
}
// onResolved(self.data)
}, 0)
} else {
setTimeout(() => {
onRejected(self.data)
}, 0)
}
})
}
myPromise.prototype.catch = function (onRejected) {
}
// promise 函数对象上挂载方法
myPromise.resolve = function (value) {
}
myPromise.reject = function (value) {
}
myPromise.all = function (value) {
}
myPromise.race = function (value) {
}
global.myPromise = myPromise
})()
// pending
// resolved
// rejected
let p = new myPromise((resolve, reject) => {
setTimeout(() => {
console.log('yes');
resolve('ok')
}, 100)
})
p.then(fn)
.then(
value => {
console.log(value , 'test');
return new Promise()
}
)
结语
以上只是笔者首日总结,后续还会完善,有用的话欢迎持续关注!!!