1. Promise.all()方法:
返回全部成功结果的数组值,如果有报错,立即返回reject,结束。
// all 方法:全部成功返回一个数组,失败就返回失败的值
myPromise.all = (values) => {//传入的是一个数组 [p1,p2]
return new myPromise((resolve, reject) => {
let results = [];
let i = 0;
let processData = (value, index) => {
results[index] = value;
i++;
if (i === values.length) {
resolve(results)
}
}
for (let i = 0; i < values.length; i++) {
//获取当前的函数
let current = values[i];
//判断是函数还是变量
if (typeof current === 'function' || (typeof current === 'object' && typeof current !== null)) {
if (typeof current.then === 'function') {
current.then(y => {
processData(y, i)
}, err => {
reject(err); //只要有一个传入的promise没有执行成功就走 reject
return;
})
} else {
//常量
processData(values[i], i)
}
}
}
})
}
2. Promise.race()方法:
返回第一个结果,不管成功或失败。
// race 方法:先快执行谁,然后返回
myPromise.race = (values) => {//传入的是一个数组[p1,p2]
return new myPromise((resolve, reject) => {
for (let i = 0; i < values.length; i++) {
let current = values[i];
if (typeof current === 'function' || (typeof current === 'object' && typeof current !== null)) {
current.then(y => {
resolve(y)
return
}, err => {
reject(err)
return
})
} else {
resolve(current)
}
}
})
}
3.源码
class myPromise {
constructor(executor) {
this.state = 'pending'; //状态值
this.value = undefined; //成功的返回值
this.reason = undefined; //失败的返回值
this.onResolveCallbacks = []; //成功的回调函数
this.onRejectCallbacks = []; //失败的回调函数
//成功
let resolve = (value) => {
if (this.state === 'pending') {
this.state = 'fullFilled'
this.value = value
this.onResolveCallbacks.forEach(fn => fn())
}
}
//失败
let reject = (reason) => {
if (this.state === 'pending') {
this.state = 'rejected'
this.reason = reason
this.onRejectCallbacks.forEach(fn => fn())
}
}
try {
//执行函数
executor(resolve, reject)
} catch (err) {
//失败则直接执行reject函数
reject(err)
}
}
then(onFullfilled, onRejected) {
// then 返回一个promise ,这样就是一个递归
let promise2 = new myPromise((resolve, reject) => {
let x;
if (this.state === 'fullFilled') {
//同步,状态为fullfilled,执行 onFullfilled,传入成功的值
setTimeout(() => {
try {
x = onFullfilled(this.value)
resolvePromise(promise2, x, resolve, reject)
} catch (error) {
//中间任何一个环节报错都走reject
reject(error)
}
}, 0)//同步无法使用promise2,所以借用setTimeout异步的方式。
}
if (this.state === 'rejected') {
//异步,rejected,执行 onRejected,传入失败的值
setTimeout(() => {
try {
x = onRejected(this.reason)
resolvePromise(promise2, x, resolve, reject)
} catch (error) {
//中间任何一个环节报错都走reject
reject(error)
}
}, 0)//同步无法使用promise2,所以借用setTimeout异步的方式。
}
//异步
if (this.state === 'pending') {
this.onResolveCallbacks.push(() => {
setTimeout(() => {
try {
x = onFullfilled(this.value)
resolvePromise(promise2, x, resolve, reject)
} catch (error) {
//中间任何一个环节报错都走reject
reject(error)
}
}, 0)//同步无法使用promise2,所以借用setTimeout异步的方式。
})
this.onRejectCallbacks.push(() => {
setTimeout(() => {
try {
x = onRejected(this.reason)
resolvePromise(promise2, x, resolve, reject)
} catch (error) {
//中间任何一个环节报错都走reject
reject(error)
}
}, 0)//同步无法使用promise2,所以借用setTimeout异步的方式。
})
}
})
return promise2;//返回promise
}
finally(callback) {
return this.then(callback, callback)
}
catch(rejectFuc) {
return this.then(null, rejectFuc);
}
}
// 这个方法的主要左右是用来判断x的值,如果x的值是一个普通的值,就直接返回x的值,如果x的值是一个promise,就要返回x.then()执行的结果,核心代码如下
const resolvePromise = (promise2, x, resolve, reject) => {
// x和promise2不能是同一个,如果是同一个就报错
if (promise2 === x) {
return reject(
new TypeError('Chaining cycle detected for promise #<promise>')
)
}
// 判断x是否是一个对象,判断函数是否是对象的方法有: typeof instanceof constructor toString
if (typeof x === 'object' && x != null || typeof x === 'function') {
let called;
try {
let then = x.then; //取 then可以报错,报错就走 reject();
if (typeof then === 'function') {
then.call(x, y => {
console.log('y', y);
if (called) return;
called = true;
resolve(y); //采用promise的成功结果,并且向下传递
resolvePromise(promise2, y, resolve, reject)
}, r => {
if (called) return;
called = true;
reject(r);//采用promise的成功结果,并且向下传递
})
} else {
resolve(x); //x不是一个函数,是一个对象
}
} catch (error) {
if (called) return;
called = true;
reject(error);//报错就走 reject();
}
} else {
// x是一个普通值
resolve(x)
}
}
myPromise.resolve = (value) => {
return new myPromise((resolve, reject) => {
resolve(value)
})
}
myPromise.reject = (value) => {
return new myPromise((resolve, reject) => {
reject(value)
})
}
// all 方法:全部成功返回一个数组,失败就返回失败的值
myPromise.all = (values) => {//传入的是一个数组 [p1,p2]
return new myPromise((resolve, reject) => {
let results = [];
let i = 0;
let processData = (value, index) => {
results[index] = value;
i++;
if (i === values.length) {
resolve(results)
}
}
for (let i = 0; i < values.length; i++) {
//获取当前的函数
let current = values[i];
//判断是函数还是变量
if (typeof current === 'function' || (typeof current === 'object' && typeof current !== null)) {
if (typeof current.then === 'function') {
current.then(y => {
processData(y, i)
}, err => {
reject(err); //只要有一个传入的promise没有执行成功就走 reject
return;
})
} else {
//常量
processData(values[i], i)
}
}
}
})
}
// race 方法:先快执行谁,然后返回
myPromise.race = (values) => {//传入的是一个数组[p1,p2]
return new myPromise((resolve, reject) => {
for (let i = 0; i < values.length; i++) {
let current = values[i];
if (typeof current === 'function' || (typeof current === 'object' && typeof current !== null)) {
current.then(y => {
resolve(y)
return
}, err => {
reject(err)
return
})
} else {
resolve(current)
}
}
})
}
let p = new myPromise((resolve, reject) => {
// resolve('成功') //走了成功就不会走失败
// throw new Error('失败了');
// reject('failed') // 走了失败就不会走成功
setTimeout(() => {
resolve('success')
}, 0)
})
p.then(res => {
console.log(res);
}, err => {
console.log(err);
})
console.log(p);