promise学习1-promise特点,手写简易版promise
1.promise特点
1.promise有三个状态 成功态(resolve) 失败态(reject) 等待态(pending)(既不成功也不失败)
举个例子,女友叫你给她买包 买 不买 不说话
promise就是一个类,所以要new。promise默认为pending状态。
2.用户自己决定成功和失败的原因,也决定最后是否成功还是失败
let promise = new Promise((resolve, reject) => {
//意思就是这里可以写业务代码,自己决定什么情况是失败什么是成功
})
console.log(promise)
3.promise默认执行器立即执行 !!!
let promise = new Promise((resolve, reject) => {
console.log(1)
})
console.log(2)
//结果是1,2
4.Promise的实例都有一个then方法,一个参数是成功的回调,一个是失败的回调
let promise = new Promise((resolve, reject) => {
console.log(1)
// resolve('成功')
})
promise.then((data) => {
console.log('success', data)
}, (err) => {
console.log('fail', err)
})
//结果 1
这里既没有抛出成功也没有抛出失败,所以不会执行后面的相关回调。
5.如果执行函数是发生了异常也会执行错误的逻辑
let promise = new Promise((resolve, reject) => {
throw new Error('失败了');
})
promise.then((data) => {
console.log('success', data)
}, (err) => {
console.log('fail', err)
})
//结果 : fail 失败了
6.promise一旦成功了就不能失败了,一旦失败了就不能成功了
2.手写promise
根据上面的特点手写promise
2.1简单的promise
const RESOLVE = 'RESOLVE';
const REJECT = 'REJECT';
const PENDING = 'PENDING';
class Promise {
constructor(executor) {
this.status = PENDING;
this.value = undefined;
this.reason = undefined;
//resolve和reject不属于实例上的
let resolve = (value) => {
if (this.status === PENDING) {
this.value = value;
this.status = RESOLVE;
}
}
let reject = (reason) => {
if (this.status === PENDING) {
this.reason = reason;
this.status = REJECT;
}
}
try {
executor(resolve, reject); //立即执行并传入resolve和reject
} catch (error) {
//错误处理 就直接走错误逻辑
reject(error);
}
}
then(onFufilled, onRejected) {
if (this.status === RESOLVE) {
onFufilled(this.value)
}
if (this.status === REJECT) {
onRejected(this.reason)
}
}
}
2.2promise的then方法
但是上面的then方法是有缺陷的,处理有异步的方法是有问题的,例如执行下面的代码就会出问题
let Promise = require('./promise')
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1)
}, 1000);
})
promise.then((data) => {
console.log('success', data)
}, (err) => {
console.log('fail', err)
})
代码执行的结果是什么都不会打印出来的
因为then方法里刚开始的状态是pending,但是之前的代码中是没有对状态为pending的进行处理的,所以是不会有什么逻辑走的,而且1秒过后状态变为resolve,但是又不会再执行方法了的。
所以我们需要做的就是第一,把pending状态的进行区分;第二,等转换为resolve或则reject状态的话还能在执行then方法。
第二种我们要使用发布订阅模式。
将上述代码改造:
const RESOLVE = 'RESOLVE';
const REJECT = 'REJECT';
const PENDING = 'PENDING';
class Promise {
constructor(executor) {
this.status = PENDING;
this.value = undefined;
this.reason = undefined;
this.onResolvedCallbacks = []; //用来存放成功的回调
this.onREjectedCallbacks = []; //用来存放失败的回调
//resolve和reject不属于实例上的
let resolve = (value) => {
if (this.status === PENDING) {
this.value = value;
this.status = RESOLVE;
this.onResolvedCallbacks.forEach(fn => fn())
}
}
let reject = (reason) => {
if (this.status === PENDING) {
this.reason = reason;
this.status = REJECT;
this.onREjectedCallbacks.forEach(fn => fn())
}
}
try {
executor(resolve, reject); //立即执行并传入resolve和reject
} catch (error) {
//错误处理 就直接走错误逻辑
reject(error);
}
}
then(onFufilled, onRejected) {
if (this.status === RESOLVE) {
onFufilled(this.value)
}
if (this.status === REJECT) {
onRejected(this.reason)
}
if(this.status === PENDING){
this.onResolvedCallbacks.push(() =>{
onFufilled(this.value)
})
this.onREjectedCallbacks.push(() =>{
onRejected(this.reason)
})
console.log('等待')
}
}
}
module.exports = Promise