作者:gochri
/*
* @Author: gochri(gochri@qq.com)
* @Date: 2022-05-08 21:48:20
* @FilePath: /undefined/Users/chengjy/test.js
* // ===== Solution Code =====
* // ===== Test Case =====
* // ===== Driver Code =====
*/
/*
Promise.all() 方法
接收一个promise的iterable类型(注:Array,Map,Set都属于ES6的iterable类型)的输入,
返回一个Promise实例,
新的实例将输入的所有promise的resolve回调的结果作为数组返回。
- 这个Promise的resolve回调执行是在所有输入的promise的resolve回调都结束,
- 或者输入的iterable里没有promise了的时候。
- 它的reject回调执行是,
-- 只要任何一个输入的promise的reject回调执行
-- 或者输入不合法的promise就会立即抛出错误
-- reject的是第一个抛出的错误信息
*/
/**
* @param {Array/Map/Set[Promise]} promiseList
* @return {Promise}
*/
const myPromiseAll = (promiseList = []) => {
return new Promise((resolve, reject) => {
let length = promiseList.length;
let res = [];
let rej = undefined;
let count = 0
for (let i in promiseList) {
let promise = promiseList[i];
Promise.resolve(promise)
.then((r) => {
res.push(r);
count++
// resolve when iterable done
if (count >= length) {
resolve(res);
}
})
.catch((rej) => {
// return first reject
reject(rej);
});
}
// 这里不能有 resolve 会先于异步返回
// resolve([])
});
};
// ------- Test Case -------
let promise = Promise.resolve(1);
let promise1, promise2, promise3;
// Case 1
promise = myPromiseAll([]);
promise
.then((values) => {
console.log("values", values);
})
.catch((error) => {
console.log("error", error);
});
// no return
// Case 2: resolve & number
promise1 = Promise.resolve(3);
promise2 = 42;
promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, "foo");
});
promise = myPromiseAll([promise1, promise2, promise3]);
promise
.then((values) => {
console.log("values", values);
})
.catch((error) => {
console.log("error", error);
});
// values [ 3, 42, 'foo' ]
// Case 3: reject
promise1 = Promise.reject(3);
promise2 = 42;
promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, "foo");
});
promise = myPromiseAll([promise1, promise2, promise3]);
promise
.then((values) => {
console.log("values", values);
})
.catch((error) => {
console.log("error", error);
});
// error 3
// error 3 先于 values 输出 因为 values 需要等待 timeout 异步操作
// Case 4: reject with timeout
promise3 = Promise.resolve(3);
promise2 = 42;
promise1 = new Promise((resolve, reject) => {
setTimeout(reject, 100, "foo");
});
promise = myPromiseAll([promise1, promise2, promise3]);
promise
.then((values) => {
console.log("values", values);
})
.catch((error) => {
console.log("error", error);
});
// error foo
// 参考 [异步回调与Promise](https://ringoer.com/frontend/promise/)
// TODO:手写promise
作者:奥兰度
/**
*
* @param {Array} promiseAry
* @returns
*/
Promise.all = function (promiseAry) {
const resultAry = []
let resolveCount = 0;
let rejectFlag = false
let rejectRes
return new Promise((resolve, reject) => {
const callback = () => {
if (rejectFlag) {
reject(rejectRes)
} else if (resolveCount >= promiseAry.length) {
resolve(resultAry)
}
}
for(let i = 0; i < promiseAry; i++) {
Promise.resolve(promiseAry[i]).then(
(val) => {
resultAry[i] = val
resolveCount++
callback()
},
(err) => {
rejectFlag = true
rejectRes = err
callback()
}
)
}
})
}
作者:xl
function promiseAll(promises) {
return new Promise((res, rej) => {
const promiseResults = [];
let iteratorIndex = 0;
let fullCount = 0;
for (const item of promises) {
let resultIndex = iteratorIndex;
iteratorIndex += 1;
// 包一层,以兼容非 promise 的情况
Promise.resolve(item).then(value => {
promiseResults[resultIndex] = value;
fullCount += 1;
if (fullCount === ) {
return res(promiseResults);
}
})
.catch(error => {
return rej(error)
})
}
// 处理空 iterator 的情况
if (iteratorIndex === 0) {
res(promiseResults)
}
});
}
作者:安静
function PromiseAll(iterator) {
const promises = Array.from(iterator);
const length = promises.length;
let index = 0;
const result = [];
return new Promise((resolve, reject) => {
for (let i = 0; i < length; i++) {
promises[i]
.then((res) => {
result[i] = res;
index++;
if (length === index) {
resolve(result);
}
})
.catch((err) => {
reject(err);
});
}
});
}
const promise1 = Promise.resolve('promise1');
const promise2 = new Promise(function (resolve, reject) {
setTimeout(resolve, 2000, 'promise2');
});
const promise3 = new Promise(function (resolve, reject) {
setTimeout(resolve, 1000, 'promise3');
});
PromiseAll([promise1, promise2, promise3]).then(function(values) {
console.log(values);
});
作者:不更新
const PROMISE_TYPE = "[object Promise]";
const STRING_AND_ARRAY_TYPE = ["[object String]", "[object Array]"];
class Promises {
static all(promises) {
return new Promise(async (resolve, reject) => {
if (
!STRING_AND_ARRAY_TYPE.includes(
Object.prototype.toString.call(promises)
)
) {
reject("argment is not iterable");
return;
}
const resloveArray = await [...promises].reduce(
(previousValue, currentValue) => {
const isPrmoise =
Object.prototype.toString.call(currentValue) === PROMISE_TYPE;
if (isPrmoise) {
currentValue.then(
(value) => {
previousValue.push(value);
},
(reason) => {
reject(reason);
}
);
} else {
previousValue.push(currentValue);
}
return previousValue;
},
[]
);
if (resloveArray.length === promises.length) {
resolve(resloveArray);
}
});
}
}
作者:
作者: