手写一个简易Promise.all
let allPromise = function (arr) {
//存储结果
let results = []
//要可以实现then和catch等,自然就是返回Promise结构
return new Promise((reslove, reject) => {
for (let i = 0; i < arr.length; i++) {
arr[i].then(data => {
results.push(data)
//如果不是全部都为resolve,那就不会在这里运行resolve
if (results.length === arr.length) {
reslove(results)
}
}, reject)
}
})
}
//创建三个Promise
const a = new Promise(function (resolve, reject) {
resolve('a resolve');
});
const b = new Promise(function (resolve, reject) {
resolve('b resolve');
});
const c = new Promise(function (resolve, reject) {
resolve('c resolve');
});
//原装的看一下结果
Promise.all([a, b, c]).then(res => {
console.log(res + ' 1');
}).catch(err => {
console.log(err + ' 1');
})
//结果:
//a resolve,b resolve,c resolve 1
//手写的看一下结果
allPromise([a, b, c]).then(res => {
console.log(res + ' 2');
}).catch(err => {
console.log(err + ' 2');
})
//结果:
//a resolve,b resolve,c resolve 2
然后改一下Promise c,改成运行reject。看下原装和手写的结果:
const c = new Promise(function (resolve, reject) {
reject('c resolve');
});
Promise.all([a, b, c]).then(res => {
console.log(res + ' 1');
}).catch(err => {
console.log(err + ' 1');
})
//c resolve 1
allPromise([a, b, c]).then(res => {
console.log(res + ' 2');
}).catch(err => {
console.log(err + ' 1');
})
//c resolve 2
以上证明可完美实现。不过优化的话,可以从传入的值是不是都是Promise函数进行优化,做一个isPromise()的函数,验证,如果是的话进入同上环节,如果不是就直接压进results中。(results.push(arr[i])
)
为了增强健壮性,还可以对传入的数组进行判断,是不是数组?(isArray()
)
手写一个Promise.race
race是哪个先出结果就执行哪个,即哪个状态改变的最快就执行哪个
let racePromise = arr => {
return new Promise((resolve, reject) => {
arr.forEach(promise => {
promise.then(resolve, reject)
})
})
}
// 通过定时器来控制那个状态率先改变
let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('success')
}, 400)
})
let p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('failed')
}, 500)
})
const p = racePromise([p1, p2])
p.then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
//如果P1设定的事件小于P2那么输出:success
//如果P1设定的事件大于P2那么输出:failed