学习笔记:promise

我心飞翔 分类:javascript

promise是什么?

Promise 是一个对象,用于表示一个异步操作的最终完成 (或失败)及其结果值。

const promise = new Promise((resolve, reject) => {
   resolve('success')
   reject('err')
})

promise.then(value => {
  console.log('resolve', value)
}, reason => {
  console.log('reject', reason)
})

 

如何实现一个promise?

一、声明一个class类

class MyPromise {
    
 }
 //function MyPromise(executor){
 //    es5构造函数
 //}
 

二、定义promise的三种状态

1、pending: 初始状态(可转变成fulfilled或rejected)。
2、fulfilled: 完成。(最终态,不可改)
3、rejected: 失败。(最终态,不可改)

// 定义三个常量表示三个状态
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
 

三、初始化promise的状态

class MyPromise {
    constructor() {
        // 初始状态为pending
        this.status = PENDING;//状态
        this.value = null;//成功的值
        this.reason = null;//失败的值
    }
 }
 

四. resolve 和 reject 方法

1. 这两个方法是要更改status的, 从pending改到fulfilled/rejected.
2. 两个函数的入参分别是value 和 reason.
 
resolve(value) {
    if (this.status === PENDING) {
       //这层判断是因为fulfilled状态只可以由pending状态改变而来
        this.status = FULFILLED;
        this.value = value;
    }
}
reject(reason) {
    if (this.status === PENDING) {
    //同理这层判断是因为rejected状态只可以由pending状态改变而来
        this.status = REJECTED;
        this.reason = reason;
    }
}
 

五. 实例化promise时的入参处理

1.入参是一个函数, 接收resolve和reject两个参数.
2.初始化promise的时候就要同步执行这个函数, 并且有任何报错都要通过reject抛出去
 
class MyPromise {
    constructor(fn) {
        // 初始状态为pending
        this.status = PENDING;//状态
        this.value = null;//成功的值
        this.reason = null;//失败的值
        try {
            fn(this.resolve.bind(this), this.reject.bind(this));
        } catch (e) {
            this.reject(e);
        }
    }

    resolve(value) {
        if (this.status === PENDING) {
           //这层判断是因为fulfilled状态只可以由pending状态改变而来
            this.status = FULFILLED;
            this.value = value;
        }
    }

    reject(reason) {
        if (this.status === PENDING) {
            //同理这层判断是因为rejected状态只可以由pending状态改变而来
            this.status = REJECTED;
            this.reason = reason;
        }
    }
 }
 

六. then方法

1. then接收两个参数, onFulfilled 和 onRejected
2. 检查并处理参数, 如果参数不是function就忽略(原样返回value或者reason)
 
class MyPromise {
constructor(fn) {
// 初始状态为pending
this.status = PENDING;//状态
this.value = null;//成功的值
this.reason = null;//失败的值
try {
fn(this.resolve.bind(this), this.reject.bind(this));
} catch (e) {
this.reject(e);
}
}
resolve(value) {
if (this.status === PENDING) {
//这层判断是因为fulfilled状态只可以由pending状态改变而来
this.status = FULFILLED;
this.value = value;
}
}
reject(reason) {
if (this.status === PENDING) {
//同理这层判断是因为rejected状态只可以由pending状态改变而来
this.status = REJECTED;
this.reason = reason;
}
}
then(onFulfilled, onRejected) {
const fulFilledFn = this.isFunction(onFulfilled) ? onFulfilled : (value) => value
const rejectedFn = this.isFunction(onRejected) ? onRejected : (reason) => {
throw reason
};
}
//检验是否为function
isFunction(param) {
return typeof param === 'function';
}
}
3. 根据当前promise的状态, 调用不同的函数
class MyPromise {
.....
//这时候then函数被调用会瞬间就会执行switch判断,那这时候如果status可能还没变成fulfilled或者rejected,很有可能还是pending
then(onFulfilled, onRejected) {
const fulFilledFn = this.isFunction(onFulfilled) ? onFulfilled : (value) => value
const rejectedFn = this.isFunction(onRejected) ? onRejected : (reason) => {
throw reason
};
switch (this.status) {
case FULFILLED: {
fulFilledFn(this.value);
break;
}
case REJECTED: {
rejectedFn(this.reason);
break;
}
}
}
//检验是否为function
isFunction(param) {
return typeof param === 'function';
}
}
4、首先要拿到所有的回调, 然后在某个时机去执行他. 需要新建两个数组, 分别存储成功和失败的回调, 调用then的时候, 如果还是pending就存入数组.
class MyPromise {
FULFILLED_CALLBACK_LIST = [] //存储成功回调
REJECTED_CALLBACK_LIST = [] //存储失败回调
.....
then(onFulfilled, onRejected) {
const fulFilledFn = this.isFunction(onFulfilled) ? onFulfilled : (value) => value
const rejectedFn = this.isFunction(onRejected) ? onRejected : (reason) => {
throw reason
};
switch (this.status) {
case FULFILLED: {
fulFilledFn(this.value);
break;
}
case REJECTED: {
rejectedFn(this.reason);
break;
}
case PENDING: {
this.FULFILLED_CALLBACK_LIST.push(fulFilledFn);
this.REJECTED_CALLBACK_LIST.push(rejectedFn);
break;
}
}
}
//检验是否为function
isFunction(param) {
return typeof param === 'function';
}
}
5、在status状态发生变化的时候调用数组里所有的函数
class MyPromise {
FULFILLED_CALLBACK_LIST = [] //存储成功回调
REJECTED_CALLBACK_LIST = [] //存储失败回调
.....
resolve(value) {
if (this.status === PENDING) {
//这层判断是因为fulfilled状态只可以由pending状态改变而来
this.status = FULFILLED;
this.value = value;
//执行存储的函数
this.FULFILLED_CALLBACK_LIST.forEach(callback => {
callback(this.value);
});
}
}
reject(reason) {
if (this.status === PENDING) {
//同理这层判断是因为rejected状态只可以由pending状态改变而来
this.status = REJECTED;
this.reason = reason;
//执行存储的函数
this.REJECTED_CALLBACK_LIST.forEach(callback => {
callback(this.reason);
});
}
}
then(onFulfilled, onRejected) {
const fulFilledFn = this.isFunction(onFulfilled) ? onFulfilled : (value) => value
const rejectedFn = this.isFunction(onRejected) ? onRejected : (reason) => {
throw reason
};
switch (this.status) {
case FULFILLED: {
fulFilledFn(this.value);
break;
}
case REJECTED: {
rejectedFn(this.reason);
break;
}
case PENDING: {
this.FULFILLED_CALLBACK_LIST.push(fulFilledFn);
this.REJECTED_CALLBACK_LIST.push(rejectedFn);
break;
}
}
}
//检验是否为function
isFunction(param) {
return typeof param === 'function';
}
}
7、then的返回值
情况1:如果 onFulfilled 或者 onRejected 抛出一个异常 e ,则新promise必须reject e
class MyPromise {
FULFILLED_CALLBACK_LIST = [] //存储成功回调
REJECTED_CALLBACK_LIST = [] //存储失败回调
.....
then(onFulfilled, onRejected) {
const fulFilledFn = this.isFunction(onFulfilled) ? onFulfilled : (value) => value
const rejectedFn = this.isFunction(onRejected) ? onRejected : (reason) => {
throw reason
};
const fulFilledFnWithCatch = (resolve, reject) => {
try {
fulFilledFn(this.value);
} catch (e) {
reject(e)
}
};
const rejectedFnWithCatch = (resolve, reject) => {
try {
rejectedFn(this.reason);
} catch (e) {
reject(e);
}
}
switch (this.status) {
case FULFILLED: {
return new MyPromise(fulFilledFnWithCatch);
}
case REJECTED: {
return new MyPromise(rejectedFnWithCatch);
}
case PENDING: {
return new MyPromise((resolve, reject) => {
this.FULFILLED_CALLBACK_LIST.push(() => fulFilledFnWithCatch(resolve, reject));
this.REJECTED_CALLBACK_LIST.push(() => rejectedFnWithCatch(resolve, reject));
});
}
}
}
//检验是否为function
isFunction(param) {
return typeof param === 'function';
}
}
情况2:如果onFulfilled不是函数且promise成功执行,那么新的promise必须返回同样的状态和val
情况3:如果onRejected不是函数且promise拒绝执行,那么新的promise必须返回同样的状态和reason
class MyPromise {
FULFILLED_CALLBACK_LIST = [] //存储成功回调
REJECTED_CALLBACK_LIST = [] //存储失败回调
.....
then(onFulfilled, onRejected) {
const fulFilledFn = this.isFunction(onFulfilled) ? onFulfilled : (value) => value
const rejectedFn = this.isFunction(onRejected) ? onRejected : (reason) => {
throw reason
};
const fulFilledFnWithCatch = (resolve, reject) => {
try {
fulFilledFn(this.value);
resolve(this.value);
} catch (e) {
reject(e)
}
};
const rejectedFnWithCatch = (resolve, reject) => {
try {
rejectedFn(this.reason);
if (this.isFunction(onRejected)) {
resolve();
}
} catch (e) {
reject(e);
}
}
switch (this.status) {
case FULFILLED: {
return new MyPromise(fulFilledFnWithCatch);
}
case REJECTED: {
return new MyPromise(rejectedFnWithCatch);
}
case PENDING: {
return new MyPromise((resolve, reject) => {
this.FULFILLED_CALLBACK_LIST.push(() => fulFilledFnWithCatch(resolve, reject));
this.REJECTED_CALLBACK_LIST.push(() => rejectedFnWithCatch(resolve, reject));
});
}
}
}
//检验是否为function
isFunction(param) {
return typeof param === 'function';
}
}
情况4:如果onFulfilled或者onRejected 返回一个值 x ,则运行resolvePromise方法
class MyPromise {
FULFILLED_CALLBACK_LIST = [] //存储成功回调
REJECTED_CALLBACK_LIST = [] //存储失败回调
.....
const fulFilledFnWithCatch = (resolve, reject, newPromise) => {
try {
if (!this.isFunction(onFulfilled)) {
resolve(this.value);
} else {
const x = fulFilledFn(this.value);
this.resolvePromise(newPromise, x, resolve, reject);
}
} catch (e) {
reject(e)
}
};
const rejectedFnWithCatch = (resolve, reject, newPromise) => {
try {
if (!this.isFunction(onRejected)) {
reject(this.reason);
} else {
const x = rejectedFn(this.reason);
this.resolvePromise(newPromise, x, resolve, reject);
}
} catch (e) {
reject(e);
}
}
switch (this.status) {
case FULFILLED: {
const newPromise = new MyPromise((resolve, reject) => fulFilledFnWithCatch(resolve, reject, newPromise));
return newPromise;
}
case REJECTED: {
const newPromise = new MyPromise((resolve, reject) => rejectedFnWithCatch(resolve, reject, newPromise));
return newPromise;
}
case PENDING: {
const newPromise = new MyPromise((resolve, reject) => {
this.FULFILLED_CALLBACK_LIST.push(() => fulFilledFnWithCatch(resolve, reject, newPromise));
this.REJECTED_CALLBACK_LIST.push(() => rejectedFnWithCatch(resolve, reject, newPromise));
});
return newPromise;
}
}
//检验是否为function
isFunction(param) {
return typeof param === 'function';
}
resolvePromise(newPromise, x, resolve, reject){}
}
8、resolvePromise
    resolvePromise(newPromise, x, resolve, reject) {
// 防止死循环
if (newPromise === x) {
return reject(new TypeError('The promise and the return value are the same'));
}
if (x instanceof MPromise) {
x.then((y) => {
resolvePromise(newPromise, y, resolve, reject);
}, reject);
} else if (typeof x === 'object' || this.isFunction(x)) {
if (x === null) {
return resolve(x);
}
let then = null;
try {
then = x.then;
} catch (error) {
return reject(error);
}
// 如果 then 是函数
if (this.isFunction(then)) {
let called = false;
try {
then.call(
x,
(y) => {
if (called) return;
called = true;
resolvePromise(promise, y, resolve, reject);
},
(r) => {
if (called) return;
called = true;
reject(r);
});
} catch (error) {
if (called) return;
reject(error);
}
} else {
resolve(x);
}
} else {
resolve(x);
}
}
9、onFulfilled 和 onRejected 是微任务
    then(onFulfilled, onRejected) {
...
const fulFilledFnWithCatch = (resolve, reject, newPromise) => {
queueMicrotask(() => {
try {
if (!this.isFunction(onFulfilled)) {
resolve(this.value);
} else {
const x = fulFilledFn(this.value);
this.resolvePromise(newPromise, x, resolve, reject);
}
} catch (e) {
reject(e)
}
})
};
const rejectedFnWithCatch = (resolve, reject, newPromise) => {
queueMicrotask(() => {
try {
if (!this.isFunction(onRejected)) {
reject(this.reason);
} else {
const x = rejectedFn(this.reason);
this.resolvePromise(newPromise, x, resolve, reject);
}
} catch (e) {
reject(e);
}
})
}
switch (this.status) {
case FULFILLED: {
const newPromise = new MPromise((resolve, reject) => fulFilledFnWithCatch(resolve, reject, newPromise));
return newPromise;
}
case REJECTED: {
const newPromise = new MPromise((resolve, reject) => rejectedFnWithCatch(resolve, reject, newPromise));
return newPromise;
}
case PENDING: {
const newPromise = new MPromise((resolve, reject) => {
this.FULFILLED_CALLBACK_LIST.push(() => fulFilledFnWithCatch(resolve, reject, newPromise));
this.REJECTED_CALLBACK_LIST.push(() => rejectedFnWithCatch(resolve, reject, newPromise));
});
return newPromise;
}
}
}
10. catch方法
catch (onRejected) {
return this.then(null, onRejected);
}
11. promise.resolve(静态方法)
将现有对象转为Promise对象,如果 Promise.resolve 方法的参数,不是具有 then 方法的对象(又称 thenable 对象),则返回一个新的 Promise 对象,且它的状态为fulfilled。
static resolve(param) {
if (param instanceof MyPromise) {
return param;
}
return new MyPromise(function (resolve) {
resolve(param);
});
}
12. promise.reject(静态方法)
返回一个新的Promise实例,该实例的状态为rejected。Promise.reject方法的参数reason,会被传递给实例的回调函数。
static reject(reason) {
return new MPromise((resolve, reject) => {
reject(reason);
});
}
路漫漫其修远兮,每天记录一点点,争取不再做菜鸟

回复

我来回复
  • 暂无回复内容