Promise分析:
就是一个类 在执行这个类的时候,需要传递一个执行器进去,执行器会立即执行
中有三种状态 分别为 成功fulfilled 失败rejected 等待pendeng
pending -> fulfilled
pending -> rejected
一旦状态确定就不可更改
和reject函数是用来更改状态的
resolve: fulfilled
reject: rejected
方法内部做的事情就是判断状态 如果状态是成功 调用成功的回调函数 如果状态是失败 调用失败的回调函数
then方式是被定义在原型对象中的
成功回调有一个参数 表示成功之后的值 then失败回调有一个参数 表示失败的原因
// promise 原理代码
const PENDING = 'pending'; // 等待
const FULFILLED = 'fulfilled'; // 成功
const REJECTED = 'rejected'; // 失败
class MyPromise {
constructor(executor) { // 接收执行器
try {
executor(, )
} catch (e) {
(e);
}
}
status = PENDING; // promise的状态
value = undefined; // 成功之后的值
reason = undefined; // 失败之后的值
successCallback = []; // 成功回调
failCallback = []; // 失败回调
// resolve和reject为什么要用箭头函数?
// 如果直接调用的话,普通函数this指向的是window或者undefined
// 用箭头函数就可以让this指向当前实例对象
resolve = value => {
// 如果状态不是等待 组织程序向下执行
if ( !== PENDING) return
// 将状态更改为成功
= FULFILLED;
// 保存成功之后的值
= value;
// 判断成功回调是否存在 如果存在 调用
// && ()
while () ()()
}
reject = reason => {
// 如果状态不是等待 组织程序向下执行
if ( !== PENDING) return
// 将状态更改为失败
= REJECTED;
// 保存失败后的原因
= reason;
// 判断失败回调是否存在 如果存在 调用
// && ()
while () ()();
}
then(successCallback, failCallback) {
successCallback = successCallback ? successCallback : value => value;
failCallback = failCallback ? failCallback : reason => {
throw reason
}; // then链式调用参数变为可选参数 例:().then().then((value)=>{(value)}) // value
let promise2 = new MyPromise((resolve, reject) => {
// 传递一个执行器 立马执行
// 判断状态
if ( === FULFILLED) {
setTimeout(() => { // 将下面的代码变成异步代码
try {
let x = successCallback()
// 判断 x 的值是普通值还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promise对象返回的结果
// 再根据promise对象返回的结果 界定调用resolve 还是reject
resolvePromise(x, resolve, reject);
} catch (e) { // 处理异常状态
reject(e)
}
}, 0)
} else if ( === REJECTED) {
setTimeout(() => { // 将下面的代码变成异步代码
try {
let x = failCallback()
resolvePromise(x, resolve, reject);
} catch (e) { // 处理异常状态
reject(e)
}
}, 0)
} else {
// 当前状态是等待
// 将成功回调和失败回调存储起来 - 多个then方法调用
(() => {
setTimeout(() => { // 将下面的代码变成异步代码
try {
let x = successCallback();
resolvePromise(x, resolve, reject);
} catch (e) { // 处理异常状态
reject(e)
}
}, 0)
});
(() => {
setTimeout(() => { // 将下面的代码变成异步代码
try {
let x = failCallback();
resolvePromise(x, resolve, reject);
} catch (e) { // 处理异常状态
reject(e)
}
}, 0)
});
}
});
return promise2;
}
finally(callback) {
/**
- 无论当前最终状态是成功还是失败,finally都会执行
- 我们可以在finally方法之后调用then方法拿到结果
- 这个函数是在原型对象上用的
* **/
return (value => {
return (callback()).then(() => value)
}, reason => {
return (callback()).then(() => {
throw reason
})
})
}
catch(failCallback) {
/**
- catch方法是为了捕获promise对象的所有错误回调的
- 直接调用then方法,然后成功的地方传递undefined,错误的地方传递reason
- catch方法是作用在原型对象上的方法
* **/
return (undefined, failCallback);
}
static all(array) {
/**
* 分析一下:
- all方法接收一个数组,数组中可以是普通值也可以是promise对象
- 数组中值得顺序一定是我们得到的结果的顺序
- promise返回值也是一个promise对象,可以调用then方法
- 如果数组中所有值是成功的,那么then里面就是成功回调,如果有一个值是失败的,那么then里面就是失败的
- 使用all方法是用类直接调用,那么all一定是一个静态方法
**/
let result = [];
let index = 0;
return new MyPromise((resolve, reject) => {
function addData(key, value) {
// 保存每个传入参数执行完毕,并存储返回值
result[key] = value;
index++;
if (index === ) {
resolve(result)
}
}
for (let i = 0; i < ; i++) {
let current = array[i];
if (current instanceof MyPromise) {
// promise对象
(value => addData(i, value), reason => reject(reason))
} else {
// 普通值
addData(i, array[i])
}
}
})
}
static resolve(value) {
/**
resolve方法的作用是将给定的值转换为promise对象 resolve的返回值的promise对象
如果参数就是一个promise对象,直接返回,如果是一个值,那么需要生成一个promise对象,把值进行返回
是Promise类的一个静态方法
* **/
if (value instanceof MyPromise) return value;
return new MyPromise(resolve => resolve(value))
}
}
function resolvePromise(x, resolve, reject) {
if (x instanceof MyPromise) {
// promise 对象
// ( value => resolve(value),reason => reject(reason))
(resolve, reject) // 简化
} else {
// 普通值
resolve(x)
}
}
= MyPromise;
测试案例:
let promise = new MyPromise((resolve,reject)=>{
// setTimeout(()=>{ // 异步操作
// resolve('成功')
// },2000)
resolve('成功')
})
let p1 = (value =>{
(value)
return p1
})
// 测试 then方法可以多次调用
// then 方法的链式调用 1.实现链式调用 2.将一个返回值作为第二个then的参数
(value => {
(value);
return p1
},reason => {
(reason)
}).then(value => {
(value)
})
// 打印结果-> 成功 成功
function f1() {
return new MyPromise(function (resolve,reject) {
setTimeout(function () {
resolve('f1')
},2000)
})
}
function f2() {
return new MyPromise(function (resolve,reject) {
setTimeout(function () {
resolve('f2')
},0)
})
}
// - 测试方法
(['a','b',f1(),f2(),'c']).then(function (result) {
(result);
})
// 打印结果-> a b f1 f2 c
// - 测试 方法
f2().finally(()=>{
('finally')
}).then((value => {
(value)
}), reason =>{
(reason)
})
// 打印结果-> flnally f2
// 测试 方法
('100').then(value => (value)) // 打印结果-> 100
(f1()).then(value => (value)) // 打印结果-> f1
function f2() {
return new MyPromise(function (resolve,reject) {
setTimeout(function () {
reject('f2---fail');
},0)
})
}
// 测试 方法
f2().then(value => {(value)})
.catch(reason => {(reason)})
// 打印结果-> f2---fail