一、Promise基本特性
- Promise三种状态:pending(进行中)、fulfilled(已完成)、rejected(已失败)
- Promise对象接受一个回调函数作为参数, 该回调函数接受两个参数,分别是成功时的回调resolve和失败时的回调reject;另外resolve的参数除了正常值以外, 还可能是一个Promise对象的实例;reject的参数通常是一个Error对象的实例。
- then方法返回一个新的Promise实例,并接收两个参数onResolved(fulfilled状态的回调);onRejected(rejected状态的回调,该参数可选)
Promise.all()
方法将多个多个Promise实例,包装成一个新的Promise实例,该方法接受一个由Promise对象组成的数组作为参数(Promise.all()
方法的参数可以不是数组,但必须具有Iterator
接口,且返回的每个成员都是Promise
实例),注意参数中只要有一个实例触发catch方法,都会触发Promise.all()方法返回的新的实例的catch方法,如果参数中的某个实例本身调用了catch方法,将不会触发Promise.all()方法返回的新实例的catch方法
二、Promise优点
1. 统一异步的API
promise逐渐被用作浏览器的异步API,统一现在各种各样的API,以及不兼容的模式和手法。
2. Promise比事件更适合处理一次性结果
promise的链式处理,在结果计算出来之前或之后注册回调函数都是可以的,都可以拿到正确的值。更适合处理一次性的结果,但不能使用 Promise 处理多次触发的事件。
3. 解决了回调地狱
采用链式写法,解决了回调地狱的问题,将异步操作以同步操作的流程表达出来。
4. 更丰富的错误处理方式
promise有更好的错误处理方式,包含了异常处理。
5. 分离了异步数据获取和业务逻辑,利于代码的复用
三、Promise缺点
- 无法取消Promise,一旦新建它就会立即执行,无法中途取消。
- 如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。
- 当处于
Pending
状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。 - Promise 真正执行回调的时候,定义 Promise 那部分实际上已经走完了,所以 Promise 的报错堆栈上下文不太友好。
四、Promise状态转换
1.初始化,状态:pending
2.当调用resolve(成功),状态:pending=>fulfilled
3.当调用reject(失败),状态:pending=>rejected
pending、fulfilled、rejected(未决定,履行,拒绝),
同一时间只能存在一种状态,且状态一旦改变就不能再变。
promise是一个构造函数,promise对象代表一项有两种可能结果(成功或失败)的任务,它还持有多个回调,出现不同结果时分别发出相应回调。
五、代码实现
(1)简单代码实现
class Promise {
constructor(executor) {
this.state = 'pending';
this.value = undefined;
this.reason = undefined;
let resolve = value => {
if (this.state === 'pending') {
this.state = 'fulfilled';
this.value = value;
}
};
let reject = reason => {
if (this.state === 'pending') {
this.state = 'rejected';
this.reason = reason;
}
};
try {
//立即执行函数
executor(resolve, reject);
} catch (err) {
reject(err);
}
}
then(onFulfilled, onRejected) {
if (this.state === 'fulfilled') {
let x = onFulfilled(this.value);
};
if (this.state === 'rejected') {
let x = onRejected(this.reason);
};
}
}
(2)面试版
function myPromise(constructor) {
let self = this;
self.status = "pending"
self.value = undefined
self.reason = undefined
function resolve(value) {
//两个 === "pending"保证状态是不可逆的
if (self.status === "pending") {
self.value = value;
self.status = "resolved";
}
}
function reject(reason) {
//两个 === "pending"保证状态是不可逆的
if (self.status === "pending") {
self.reason = reason;
self.status = "rejected";
}
}
//捕获构造异常
try {
constructor(resolve, reject);
} catch (e) {
reject(e)
}
}
myPromise.prototype.then = function (onFulfilled, onRejected) {
let self = this;
switch (self.status) {
case "resolve": onFulfilled(self.value); break;
case "reject": onRejected(self.reason);break;
default;
}
}
//测试
var p = new myPromise(function (resolve, reject) {
resolve(1)
})
p.then(function(x) {
console.log(x)//1
})