promise相关
- 什么是
promise规范?- 就像
es是js的规范,js是es的实现,js中的原生promise是对promise/A+规范的实现 promise不止一个规范,有很多社区规范,比较全面的是promise/A+
- 就像
js中promise的then是微任务,是因为浏览器引擎是用微任务实现的,规范中之规定了是异步任务即可
手写promise
原生promise形态:
let promise = new Promise((reslove, reject) => {})
需要实现和注意的点
- 基本形态
构造器来创建,参数传入函数,函数的参数是两个函数,外部可以用型参来调用类内部的函数,要注意this的绑定问题- 实例属性
- 状态
- 结果值
- 回调函数数组(状态不会立即改变,用数组收集
then中的回调函数)
- 状态管理函数
resolve()reject()- 是个
异步任务这里使用setTimeout()宏任务模拟异步,但注意js中promise是个微任务 - 修改实例的状态,和结果值
- 遍历执行回调函数数组中的函数
- 是个
- 监听状态改变的函数
then,catchthen(f1, f2)参数必须是函数then是链式调用的resovePromise的实现(具体后面说明)
all()race()的实现
代码
class myPromise {
//状态写成静态函数? 见插播知识点
static PENDING = 'pending';
static FULFILLED = 'fulfiled';
static REJECTED = 'rejected';
// 方便看到整体的结构,列出需要实现的函数
constructor(func) {
...//拆解到下面代码中
}
resolve(result) {
...//拆解到下面代码中
}
reject(reason) {
...//拆解到下面代码中
}
then(onResolved, onRejected) {
...//拆解到下面代码中
}
race(paramsArr) {
...//拆解到下面代码中
}
}
function resolvePromise() {
...//拆解到下面代码中
}
插播知识点:
静态函数和静态属性;
(1)基本形态和使用方法: 代码示例中展示了
(2)好处:无需创建实例;共享数据;避免全局命名冲突
constructor(func) {
this.promiseStatus = myPromise.PENDING;
this.promiseResult = null;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
try {
/**
* reslove是在实例外部调用,会使this丢失,
* 用bind绑定this为实例中的this
*/
func(this.resolve.bind(this), this.reject.bind(this));
} catch (error) {
this.reject(error);
}
}
resolve(result) {
setTimeout(() => {
if (this.promiseStatus === myPromise.PENDING) {
this.promiseStatus = myPromise.FULFILLED;
this.promiseResult = result;
/**
* 执行then中收集的回调函数
*/
this.onFulfilledCallbacks.forEach(callback => callback(result));
}
});
}
reject(reason) {
setTimeout(() => {
if (this.promiseStatus === myPromise.PENDING) {
this.promiseStatus = myPromise.REJECTED;
this.promiseResult = reason;
this.onRejectedCallbacks.forEach(callback => callback(reason));
}
});
}
/**
* 返回promise 可以链式调用
* 根据状态来执行
* 回调函数执行返回的值需要resolvePromise来处理
* @param {*} onResolved
* @param {*} onRejected
* @returns
*/
then(onResolved, onRejected) {
let promise = new myPromise((resolve, reject) => {
if (this.promiseStatus === myPromise.PENDING) {
this.onFulfilledCallbacks.push(() => {
setTimeout(() => {
try {
if (typeof onResolved !== 'function') {
resolve(this.promiseResult);
} else {
let value = onResolved(this.promiseResult);
resolvePromise(promise, value, resolve, reject);
}
} catch (error) {
reject(error);
}
});
});
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
if (typeof onRejected !== 'function') {
reject(this.promiseResult);
} else {
let value = onRejected(this.promiseResult);
resolvePromise(promise, value, resolve, reject);
}
} catch (error) {
reject(error);
}
});
});
}
if (this.promiseStatus === myPromise.FULFILLED) {
setTimeout(() => {
try {
if (typeof onResolved !== 'function') {
resolve(this.promiseResult);
} else {
let value = onResolved(this.promiseResult);
resolvePromise(promise, value, resolve, reject);
}
} catch (error) {
reject(error);
}
});
}
if (this.promiseStatus === myPromise.REJECTED) {
setTimeout(() => {
try {
if (typeof onRejected !== 'function') {
reject(this.promiseResult);
} else {
let value = onRejected(this.promiseResult);
resolvePromise(promise, value, resolve, reject);
}
} catch (error) {
reject(error);
}
});
}
});
return promise;
}
//处理promise链式
/**
* then结果返回值处理函数,处理回调函数是promise的情况
* 递归查找then的链
/**
* x值的处理
* (1)x是基本类型
* (2)是我们手写定义的promise对象
* (3)是promise实例
*/
* @param {*} promise then的返回值promise
* @param {*} x then回调函数的返回值
* @param {*} resolve 对x的处理函数 then的返回值promise中的
* @param {*} reject 对x的处理函数 then的返回值promise中的
* @returns
*/
function resolvePromise(promise, x, resolve, reject) {
if (x === promise) {
throw new TypeError('chaining cycle detected for promise');
}
if (x instanceof myPromise) {
x.then(y => {
resolvePromise(promise, y, resolve, reject);
}, reject);
} else if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
try {
// 有then属性的对象 或者其他规范的promise,获取then属性,
// get操作可能会有异常 需要try...catch
var then = x.then;
} catch (error) {
return reject(error);
}
// then应该是个可执行函数
if (typeof then === 'function') {
// 添加一个锁,只执行一次
let called = false;
try {
then.call( //执行 绑定x上下文
x,
y => {
if (called) return;
called = true;
resolvePromise(promise, y, resolve, reject); //递归处理
},
rej => {
if (called) return;
called = true;
reject(rej);
}
);
} catch (error) {
if (called) return;
called = true;
reject(error);
}
} else {
resolve(x); //then不可执行,x只是一个有then属性的类promise对象
}
} else {
resolve(x); //基本类型值处理
}
}
over!
flag:后续完善promise相关的知识:promise的设计理念; promise的执行顺序;基于promise封装的异步处理函数axios,fetch; promise的语法糖async/await