New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
第 24 题:实现 Promise.all #30
Comments
1) 核心思路
2)实现代码 function promiseAll(promises) {
return new Promise(function(resolve, reject) {
if(!Array.isArray(promises)){
throw new TypeError(`argument must be a array`)
}
var resolvedCounter = 0;
var promiseNum = promises.length;
var resolvedResult = [];
for (let i = 0; i < promiseNum; i++) {
Promise.resolve(promises[i]).then(value=>{
resolvedCounter++;
resolvedResult[i] = value;
if (resolvedCounter == promiseNum) {
return resolve(resolvedResult)
}
},error=>{
return reject(error)
})
}
})
}
// test
let p1 = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(1)
}, 1000)
})
let p2 = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(2)
}, 2000)
})
let p3 = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(3)
}, 3000)
})
promiseAll([p3, p1, p2]).then(res => {
console.log(res) // [3, 1, 2]
}) |
/**
* Promise.all
* @description 当这个数组里的所有promise对象全部变为resolve状态的时候,才会resolve, 当有一个promise对象变为reject状态时,就不再执行直接 reject
* @param {*} values promise对象组成的数组作为参数
*/
Promise.prototype.all = (values)=>{
return new Promise((resolve,reject)=>{
let resultArr = []
let count = 0
let resultByKey = (value,index)=>{
resultArr[index] = value
if(++count === values.length){
resolve(resultArr)
}
}
values.forEach((promise,index)=>{
promise.then((value)=>{
resultByKey(value,index)
},reject)
})
})
} |
Promise.all = function (promises) {
return new Promise((resolve, reject) => {
if (!Array.isArray(promises)) {
throw new Error('argument must be a array');
}
// 用来记录Promise成功的次数
let resolveCount = 0,
// 用来保存Promise成功的结果
resolveDataList = [];
for (let index = 0, len = promises.length; index < len; index++) {
const p = promises[index];
Promise.resolve(p).then(data => {
resolveDataList[index] = data;
// promise成功次数等于promises数组长度,则成功
if (++resolveCount === len) {
resolve(resolveDataList);
}
// 有一个失败就失败
}, reject);
}
});
}
Promise.race = (promises = []) => {
return new Promise((resolve, reject) => {
if (!Array.isArray(promises)) {
throw new TypeError(`argument must be a array`);
}
for (const p of promises) {
// 有一个成功就返回成功状态的promise
// 有一个失败就返回失败状态的promise
p.then(resolve, reject);
}
});
}
// Promise.finally() 最终的,无论如何finally中传递的回调函数 必须会执行,如果返回一个promise,会等待这个Promise执行完成
Promise.prototype.finally = function(callback){
return this.then(res => {
// 如果then方法返回一个Promise, 就会等待这个方法执行完毕,所以需要包装成Promise才能等待
return Promise.resolve(callback()).then(() => res);
}, err => {
return Promise.resolve(callback()).then(() => {
throw err;
})
});
}
let p1 = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(1)
}, 1000)
})
let p2 = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(2)
}, 2000)
})
let p3 = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(3)
}, 3000)
})
Promise.all([p3, p1, p2]).then(res => {
console.log(res) // [3, 1, 2]
}); |
Promise.myAll = function (arr) {
const length = arr.length;
let result = new Array(length);
let count = 0;
let succeedCount = 0;
let resolveAllFn = null;
let rejectAllFn = null;
let someErr = null;
function addcount() {
count++;
if (count === length) {
succeedCount === length
? resolveAllFn(result)
: rejectAllFn(someErr)
}
}
for (const [i, p] of arr.entries()) {
Promise.resolve(p).then((res) => {
result[i] = res;
succeedCount++;
addcount();
}, (err) => {
someErr = err;
addcount();
})
}
return new Promise((rs, rj) => {
resolveAllFn = rs;
rejectAllFn = rj;
})
}
Promise.myAll([
new Promise(rs=>{
setTimeout(() => {
rs(0)
}, 1000);
}),
Promise.resolve(1),
]).then((res) => {
console.log(res);//[ 0, 1]
});
Promise.myAll([
new Promise((_, rj)=>{
setTimeout(() => {
rj(0)
}, 1000);
}),
Promise.resolve(1),
]).then(() => {},err=>{
console.log(err); //0
}); |
Promise.all = (...promises) => {
const results = [];
const merged = promises.reduce(
(acc, p) => acc.then(() => p).then(r => results.push(r)),
Promise.resolve(null));
return merged.then(() => results);
}; from: https://eddmann.com/posts/implementing-promise-all-and-promise-race-in-javascript/ |
|
function all(promiseList) {
return new Promise((resolve, reject) => {
if(!promiseList || !promiseList.length) return resolve([])
let count = 0
let length = promiseList.length
let result = []
for (let i = 0; i < length; i++) {
Promise.resolve(promiseList[i]).then(value => {
result[count++] = value
if(count === length) resolve(result)
}, reason => {
reject(reason)
})
}
})
}
function race(promiseList) {
return new Promise((resolve, reject) => {
if(!promiseList || !promiseList.length) return resolve()
let length = promiseList.length
for (let i = 0; i < length; i++) {
Promise.resolve(promiseList[i]).then(value => {
resolve(value)
}, reason => {
reject(reason)
})
}
})
}
function allSettled(promiseList) {
return new Promise((resolve, reject) => {
if(!promiseList || !promiseList.length) return resolve([])
let count = 0
let length = promiseList.length
let result = []
for (let i = 0; i < length; i++) {
Promise.resolve(promiseList[i]).then(value => {
result[count++] = {
value,
status: 'fulfilled'
}
if(count === length) resolve(result)
}, reason => {
result[count++] = {
reason,
status: 'rejected'
}
if(count === length) resolve(result)
})
}
})
}
var promiseList = new Array(3).fill(0).map((item, index) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(index)
}, index * 1000)
})
})
Promise.all(promiseList).then(list => {
console.log(list)
})
all(promiseList).then(list => {
console.log(list)
})
Promise.race(promiseList).then(list => {
console.log(list)
})
race(promiseList).then(value => {
console.log(value)
})
Promise.allSettled(promiseList).then(list => {
console.log(list)
})
allSettled(promiseList).then(list => {
console.log(list)
}) |
function all(promiseList) {
return new Promise((resolve, reject) => {
if(!promiseList || !promiseList.length) return resolve([])
let count = 0
let length = promiseList.length
let result = []
for (let i = 0; i < length; i++) {
Promise.resolve(promiseList[i]).then(value => {
result[count++] = value
if(count === length) resolve(result)
}, reason => {
reject(reason)
})
}
})
}
function race(promiseList) {
return new Promise((resolve, reject) => {
if(!promiseList || !promiseList.length) return resolve()
let length = promiseList.length
for (let i = 0; i < length; i++) {
Promise.resolve(promiseList[i]).then(value => {
resolve(value)
}, reason => {
reject(reason)
})
}
})
}
function allSettled(promiseList) {
return new Promise((resolve, reject) => {
if(!promiseList || !promiseList.length) return resolve([])
let count = 0
let length = promiseList.length
let result = []
for (let i = 0; i < length; i++) {
Promise.resolve(promiseList[i]).then(value => {
result[count++] = {
value,
status: 'fulfilled'
}
if(count === length) resolve(result)
}, reason => {
result[count++] = {
reason,
status: 'rejected'
}
if(count === length) resolve(result)
})
}
})
}
var promiseList = new Array(3).fill(0).map((item, index) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(index)
}, index * 1000)
})
})
Promise.all(promiseList).then(list => {
console.log(list)
})
all(promiseList).then(list => {
console.log(list)
})
Promise.race(promiseList).then(list => {
console.log(list)
})
race(promiseList).then(value => {
console.log(value)
})
Promise.allSettled(promiseList).then(list => {
console.log(list)
})
allSettled(promiseList).then(list => {
console.log(list)
}) |
const promiseAll = (promises) => {
const newPromise = new Promise(function (resolve, reject) {
if (!Array.isArray(promises)) reject(new Error('promises is not array'));
const promiseLength = promises.length;
let promiseResolveCount = 0;
let promiseResolveResult = [];
for (let promise in promises) {
Promise.resolve(promise).then(value => {
promiseResolveResult.push(value);
promiseResolveCount++;
if (promiseResolveCount === promiseLength) resolve(promiseResolveResult);
}, error => {
reject(error);
})
}
});
return newPromise;
}
// test
let p1 = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(1)
}, 1000)
})
let p2 = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(2)
}, 2000)
})
let p3 = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(3)
}, 3000)
})
promiseAll([p3, p1, p2]).then(res => {
console.log(res) // [3, 1, 2]
}) |
async function promiseAll(ary = []) {
if (typeof ary[Symbol.iterator] !== 'function') {
throw new Error('尚未拥有Iterator接口')
}
const returnAry = []
try {
for (const val of ary) {
returnAry.push(await val)
}
return returnAry
} catch (err) {
console.log('all error:', err)
return err
}
}
let p1 = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(1)
}, 1000)
})
let p2 = new Promise(function(resolve, reject) {
setTimeout(function() {
// resolve(2)
reject('demo error test')
}, 2000)
})
let p3 = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(3)
}, 3000)
})
promiseAll([p3, p1, p2]).then(res => {
console.log(res) // [3, 1, 2]
}) |
Promise.all = promises => {
}; |
Promise.all = function (promises) {
return new Promise((resolve, reject) => {
let len = promises.length
const result = []
promises.forEach((promise, i) => {
Promise.resolve(promise).then((res) => {
len--
result[i] = res
if (len === 0) resolve(result)
}).catch(err => {
reject(err)
})
})
})
}
const promise1 = new Promise((resolve) => {
setTimeout(() => {
resolve(1)
}, 2000)
})
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(2)
}, 100)
})
Promise.all([promise1, promise2]).then(res => {
console.log(res)
}).catch(err => {
console.error(err)
}) |
/**
* Promise.all
* 接收一个promise列表
* 返回一个新的Promise对象
* 当所有promise都resolved时,按入参顺序resolve出value列表
* 如果有promise rejected,立刻reject该error
*/ 上次手写的MyPromiseclass MyPromise {
constructor(executor) {
this.status = "pending";
this.value = undefined;
this.error = undefined;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
const resolve = (data) => {
if (this.status === "pending") {
this.status = "fulfilled";
this.value = data;
this.onFulfilledCallbacks.forEach((cb) => cb(this.value));
}
};
const reject = (error) => {
if (this.status === "pending") {
this.status = "rejected";
this.error = error;
this.onRejectedCallbacks.forEach((cb) => cb(this.error));
}
};
try {
executor(resolve, reject);
} catch (error) {
reject(error);
}
}
then(onFulfilled, onRejected) {
return new MyPromise((resolve, reject) => {
if (this.status === "fulfilled") {
try {
const result = onFulfilled(this.value);
resolve(result);
} catch (error) {
reject(error);
}
} else if (this.status === "rejected") {
try {
const result = onRejected(this.error);
resolve(result);
} catch (error) {
reject(error);
}
} else {
this.onFulfilledCallbacks.push((value) => {
try {
const result = onFulfilled(value);
resolve(result);
} catch (error) {
reject(error);
}
});
this.onRejectedCallbacks.push((error) => {
try {
const result = onRejected(error);
resolve(result);
} catch (err) {
reject(err);
}
});
}
});
}
} all方法MyPromise.all = function (promiseList) {
return new MyPromise((resolve, reject) => {
const valueList = promiseList.map(() => undefined);
let successCount = 0;
promiseList.forEach((p, index) => {
p.then(
(res) => {
valueList[index] = res;
successCount++;
if (successCount.length === promiseList.length) {
resolve(valueList);
}
},
(err) => {
reject(err);
}
);
});
});
}; 测试const p1 = new MyPromise((res, rej) => {
setTimeout(() => {
res(1);
}, 5000);
});
const p2 = new MyPromise((res, rej) => {
setTimeout(() => {
res(2);
}, 6000);
});
const p3 = new MyPromise((res, rej) => {
setTimeout(() => {
rej(new Error(3));
}, 1500);
});
MyPromise.all([p1, p2, p3]).then(
(res) => console.log(res),
(err) => console.error(err)
); |
The text was updated successfully, but these errors were encountered: