JavaScript 是单线程、异步、非阻塞、解释型脚本语言。实际开发中很多执行要基于异步任务,所以要解决异步的问题。
- 异步编程方式:
- 回调,但是回调多了代码会形成回调地狱
- 发布订阅
- 事件监听
- Promise
- generator
- async/await-generator封装的语法糖
Promise
Promise实例支持链式调用,代码清晰,易于维护,低耦合
-
Promise源码的重点
- 处理异步,保证代码按顺序执行
- 处理链式调用,保证返回一个新的Promise实例
- 处理resolve中传入的是一个新的Promise实例
- 处理then方法中传入的执行函数返回的值为一个新的Promise实例
-
分析
- resolve是为下一个promise实例赋值和更改状态服务的
- 规范状态只能从pending到fulfilled或者rejected,执行resolve和reject更改状态,即当前实例状态更改将不会再重复执行
- 其实每一次返回的都是一个新的实例,并且收集函数数组中也最多只有一个等待执行回调函数,等待当前promise状态改变执行
-
简单实现代码
const PENDING = 'pending';//等待状态
const FUFILLED = 'fulfilled';// 成功状态
const REJECTED = 'rejected';// 失败状态
class Promise {
constructor(excutor) {
this.state = PENDING;// 初始化状态
this.value = undefined;// 初始化值
this.result = undefined;// 初始化失败原因
this.onFulfilledCB = [];// 成功状态回调收集函数数组
this.onRejectedCB = [];// 失败装填回调收集函数数组
// 状态pending=>fulfilled
// 3---------处理传入的值为promise实例(需要拿到当前promise的状态和值)
let resolve = (value) => {
if (value && value.then && value instanceof Promise) {
// 此时的resolve是最开始的promise的,通过then内部通过value内部的状态调用不同的状态函数进行赋值,和状态更改
// 此处兼容value内部的是异步和同步(因为then内部已经处理好了)
value.then(resolve, reject)
return;
}
//这样状态只能改变一次,防止多次调用resolve
if (this.state === PENDING) {
this.state = FUFILLED;
this.value = value;
//此处将then中回调收集
setTimeout(() => {
// this.value是需要在异步中使用的值
this.onFulfilledCB.forEach((cb) => {
cb(this.value)
})
})
}
}
// 状态pending=>rejected
let reject = (result) => {
//这样状态只能改变一次,防止多次调用resolve
if (this.state == PENDING) {
this.state = REJECTED;
this.result = result;
setTimeout(() => {
// this.value是需要在异步中使用的值
this.onRejectedCB.forEach(cb => {
cb(this.result)
})
})
}
}
try {
// 执行函数
excutor(resolve, reject)
} catch (er) {
reject(er);
}
}
then(onFulfilled, onRejected) {
//保证是一个函数
onFulfilled = Object.prototype.toString.call(onFulfilled) === '[object Function]' ? onFulfilled : value => value;
onRejected = Object.prototype.toString.call(onRejected) === '[object Function]' ? onRejected : result => {
throw reason
};
// 当状态已经改变直接执行回调
if (this.state == FUFILLED) {
//2-------处理链式调用(返回一个新的p实例,并且将返回值通过resolve赋值给value,也就是下一次调用回调使用的value)
return new Promise((resolve, reject) => {
let x = onFulfilled(this.value);
if (x instanceof Promise) {
x.then(resolve, reject);
return;
}
resolve(x)
})
}
// 当状态已经改变直接执行回调
if (this.state == REJECTED) {
return new Promise((resolve, reject) => {
let x = onRejected(this.result);
if (x instanceof Promise) {
x.then(resolve, reject);
return;
}
reject(x)
})
}
// 1--------处理异步
// 2--------处理异步链式调用
// 4--------处理返回值x为promise的情况(需要将返回的promise的状态和值传递下去)
if (this.state == PENDING) {
let _this = this;
return new Promise((resolve, reject) => {
_this.onFulfilledCB.push(() => {
let x = onFulfilled(_this.value);
if (x instanceof Promise) {
x.then(resolve, reject);
return;
}
//调用时给新的promise实例赋值
resolve(x)
});
_this.onRejectedCB.push(() => {
let x = onRejected(_this.result);
if (x instanceof Promise) {
x.then(resolve, reject);
return;
}
//调用时给新的promise实例赋值
reject(x)
});
})
}
}
catch () {
}
//静态方法
static resolve() {
}
static reject() {
}
static race() {
}
static all() {
}
}