const p = new Promise((resolve, reject)=>{
console.log('这里会立即执行');
resolve('成功')
})
1.构造函数
- new Promise()创建实例,需要定义class
- 会先执行构造函数
- 构造函数接受一个回调函数((resolve, reject) => {...})作为参数
- 这个回调函数,接受resolve,reject两个函数参数,并且resolve,reject不是外部传递的,是自身的函数
- 构造函数内,会直接执行这个回调函数
class Prms{
constructor(fun){
const resolve = (result) =>{ console.log('resolve执行', result)};
const reject = (result) =>{ console.log('reject执行', result)};
fun(resolve,reject);
}
}
const p = new Prms((resolve, reject)=>{
console.log('这里会立即执行');
resolve('成功')
})
2. 状态及结果
- 状态(pending, fulfilled, rejected),并且状态不可逆
- 结果,resolve,reject对应的成功/失败结果
- 这两个是实例属性
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class Prms {
state = PENDING;
result = undefined;
constructor(fun) { // 构造函数的this,就是实例对象
const resolve = (result) => {
if (this.state == 'pending') {
this.state = FULFILLED;
this.result = result;
}
};
const reject = (result) => {
if (this.state == 'pending') {
this.state = REJECTED;
this.result = result;
}
};
fun(resolve, reject);
}
}
const p = new Prms((resolve, reject) => {
console.log('这里会立即执行');
resolve('成功')
})
p.state p.result
3. then方法 - 回调
p.then((res)=>{ 成功回调 }, (res)=>{ 失败回调 })
- then为实例方法,接受两个回调函数作为参数,
- 成功回调/失败回调,会接受reolve/reject的结果,即this.result
- 回调函数是可选的,如果不传,会有默认处理
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : x => x;
onRejected = typeof onRejected === 'function' ? onRejected : x => { throw x };
if (this.state === FULFILLED) {
onFulfilled(this.result)
} else if (this.state === REJECTED) {
onRejected(this.result)
}
}
3. then - 异步/多次调用
异步任务中,.then()调用时,状态还没改变
const p = new Prms((resolve, reject) => {
setTimeout(() => {
console.log('这里会立即执行');
resolve('成功结果')
}, 1000)
})
p.then((res) => { console.log('then1成功', res) });
p.then((res) => { console.log('then2成功', res) });
- 添加实例属性handler,保存.then方法的回调函数
- 执行.then方法,如果状态还未改变,则存到handler中
- resolve/reject中,改变状态后,执行handler中的函数
#handlers = [] // [{onFulfilled, onRejected}, {...}]
const resolve = (result) => {
if (this.state == 'pending') {
this.state = FULFILLED;
this.result = result;
// 调用成功回调函数
this.#handlers.forEach((fun) => fun.onFulfilled(result))
}
};
then(onFulfilled, onRejected) {
...
if (this.state === FULFILLED) {
onFulfilled(this.result)
} else if (this.state === REJECTED) {
onRejected(this.result)
} else {
// 保存回调函数
this.#handlers.push({ onFulfilled, onRejected })
}
}
4. 异步任务
.then()方法是微任务,要在同步任务后执行
console.log('aaaa');
const p = new Prms((resolve, reject) => {
resolve('success');
})
p.then((res) => { console.log(res) })
console.log('bbbb')
应该是 aaaa bbbb success
- 封装一个异步执行的函数,接受一个函数为参数,异步执行
function runAsync(callback) {
setTimeout(callback, 0)
}
.then中的方法需要异步
then(onFulfilled, onRejected) {
...
if (this.state === FULFILLED) {
runAsync(() => onFulfilled(this.result));
} else if (this.state === REJECTED) {
runAsync(() => onRejected(this.result));
} else {
this.#handlers.push({
onFulfilled: () => runAsync(() => onFulfilled(this.result)),
onRejected: () => runAsync(() => onRejected(this.result))
})
}
}
5. 链式编程
p.then(res => { return 2;}).then(res=> {...}, err=>{...})
- .then()方法返回的结果,可以继续.then调用 --- .then()返回一个promise实例
- .then()又可以获取上一个.then()返回的内容 --- promise实例resolve/reject
- .then1()如果抛错,.then2()的onRejected获取执行
then(onFulfilled, onRejected) {
...
1. 返回新promise实例
const p2 = new Prms((resolve, reject) => {
---------创建promise,传递的回调函数,这里会立刻执行
if (this.state === FULFILLED) {
runAsync(() => {
try {
// 获取.then1()返回的结果
const res = onFulfilled(this.result)
// 成功 / 失败对应状态
resolve(res);
} catch (error) {
reject(error);
}
});
} else if (this.state === REJECTED) { ... }
return p2;
}
}
- 处理.then返回promise对象
...上述.then方法中
if (this.state === FULFILLED) {
runAsync(() => {
try {
const res = onFulfilled(this.result)
// 判断如果返回promise对象
if (res instanceof Prms) {
对象内部已经 resolve/reject过,这里.then直接获取对应结果
res.then(res => resolve(res), err => reject(err))
} else {
resolve(res);
}
} catch (error) {
reject(error);
}
});
}
- 处理重复引用 p.then()回调函数中返回值,等于 p.then()的返回值
const p1 = new Promise((resolve) => {
resolve('pp');
})
const p2 = p2.then((res) => {
return p2;
})
正常是要抛错的
// p2为.then方法返回的结果,res为.then方法回调返回的结果
const res = onFulfilled(this.result);
if (res === p2) {
throw new TypeError('Chaining cycle detected for promise #<Promise>')
}
- rejected状态处理
- 同fulfilled状态的操作
- 可以把.then返回promise实例的操作封装一下
function resolvePromise(p2, r, resolve, reject) {
if (r === p2) {
throw new TypeError('Chaining cycle detected for promise #<Promise>')
}
if (r instanceof Prms) {
r.then(res => resolve(res), err => reject(err))
} else {
resolve(r);
}
}
if (this.state === FULFILLED) {
runAsync(() => {
try {
const r = onFulfilled(this.result)
resolvePromise(p2, r, resolve, reject);
} catch (error) {
reject(error);
}
});
} else if (this.state === REJECTED) {
runAsync(() => {
try {
const r = onRejected(this.result)
resolvePromise(p2, r, resolve, reject);
} catch (error) {
reject(error);
}
});
}
- pending状态处理 操作同上
else {
this.#handlers.push({
onFulfilled: () => runAsync(() => {
try {
const r = onFulfilled(this.result)
resolvePromise(p2, r, resolve, reject);
} catch (error) {
reject(error);
}
}),
onRejected: () => runAsync(() => {
try {
const r = onRejected(this.result)
resolvePromise(p2, r, resolve, reject);
} catch (error) {
reject(error);
}
})
})
}
6. 实例方法
- catch - 就是调用.then方法,只传第二个参数
catch(onRejected) {
return this.then(undefined, onRejected)
}
--------构造函数执行要捕获一下错误,确保可以走到catch中
try {
fun(resolve, reject);
} catch (error) {
reject(error)
}
- finally
finally(onFinally) {
return this.then(onFinally, onFinally)
}
7. 静态方法
- resolve
- 传入的值如果是promise对象,直接返回
- 普通值,转为promise返回(fulfilled状态)
static resolve(value){
if(value instanceof Prms){
return value
}
return new Prms((resolve)=>{
resolve(value)
})
}
- reject
- 直接返回一个已拒绝的对象
static reject(value){
return new Prms((undefined, reject)={
reject(value)
})
}
- race
- 返回一个promise
- 传入的参数是数组
- 等待第一个promise状态确定
static race(promises){
return new Prms(()=>{
if(!Array.isArray(promises)){
reject(new TypeError('Argument is not iterable'))
}
// 等待状态确定
promises.forEach((p)=>{
// 数组元素可能不是promise对象
Prms.resolve(p).then(
res=>resolve(res),
err=>reject(err)
)
})
})
}
- all
- 接受一个参数(数组),返回一个promise对象
- 当传入的所有promise都成功,返回的promise也成功,返回一个(成功的值的)数组
- 任意一个失败,则返回的promise失败,带有第一个失败的promise原因
static all(promises){
return new Prms((resolve, reject)=>{
if (!Array.isArray(promises)) {
reject(new TypeError('Argument is not iterable'))
}
// 空数组直接兑现
promises.length ===0 && resolve(promises)
const results = [];
let count = 0;
promises.forEach((p, index) => {
Prms.resolve(p).then(
res => {
// 不用push, 异步顺序可能不一致
results[index] = res;
// 判断状态是否全部改变
count ++;
count === promises.length && resolve(results)
},
err => {
reject(err)
}
)
})
})
}