作者:gochri

    1. /*
    2. * @Author: gochri(gochri@qq.com)
    3. * @Date: 2022-05-08 21:48:20
    4. * @FilePath: /undefined/Users/chengjy/test.js
    5. * // ===== Solution Code =====
    6. * // ===== Test Case =====
    7. * // ===== Driver Code =====
    8. */
    9. /*
    10. Promise.all() 方法
    11. 接收一个promise的iterable类型(注:Array,Map,Set都属于ES6的iterable类型)的输入,
    12. 返回一个Promise实例,
    13. 新的实例将输入的所有promise的resolve回调的结果作为数组返回。
    14. - 这个Promise的resolve回调执行是在所有输入的promise的resolve回调都结束,
    15. - 或者输入的iterable里没有promise了的时候。
    16. - 它的reject回调执行是,
    17. -- 只要任何一个输入的promise的reject回调执行
    18. -- 或者输入不合法的promise就会立即抛出错误
    19. -- reject的是第一个抛出的错误信息
    20. */
    21. /**
    22. * @param {Array/Map/Set[Promise]} promiseList
    23. * @return {Promise}
    24. */
    25. const myPromiseAll = (promiseList = []) => {
    26. return new Promise((resolve, reject) => {
    27. let length = promiseList.length;
    28. let res = [];
    29. let rej = undefined;
    30. let count = 0
    31. for (let i in promiseList) {
    32. let promise = promiseList[i];
    33. Promise.resolve(promise)
    34. .then((r) => {
    35. res.push(r);
    36. count++
    37. // resolve when iterable done
    38. if (count >= length) {
    39. resolve(res);
    40. }
    41. })
    42. .catch((rej) => {
    43. // return first reject
    44. reject(rej);
    45. });
    46. }
    47. // 这里不能有 resolve 会先于异步返回
    48. // resolve([])
    49. });
    50. };
    51. // ------- Test Case -------
    52. let promise = Promise.resolve(1);
    53. let promise1, promise2, promise3;
    54. // Case 1
    55. promise = myPromiseAll([]);
    56. promise
    57. .then((values) => {
    58. console.log("values", values);
    59. })
    60. .catch((error) => {
    61. console.log("error", error);
    62. });
    63. // no return
    64. // Case 2: resolve & number
    65. promise1 = Promise.resolve(3);
    66. promise2 = 42;
    67. promise3 = new Promise((resolve, reject) => {
    68. setTimeout(resolve, 100, "foo");
    69. });
    70. promise = myPromiseAll([promise1, promise2, promise3]);
    71. promise
    72. .then((values) => {
    73. console.log("values", values);
    74. })
    75. .catch((error) => {
    76. console.log("error", error);
    77. });
    78. // values [ 3, 42, 'foo' ]
    79. // Case 3: reject
    80. promise1 = Promise.reject(3);
    81. promise2 = 42;
    82. promise3 = new Promise((resolve, reject) => {
    83. setTimeout(resolve, 100, "foo");
    84. });
    85. promise = myPromiseAll([promise1, promise2, promise3]);
    86. promise
    87. .then((values) => {
    88. console.log("values", values);
    89. })
    90. .catch((error) => {
    91. console.log("error", error);
    92. });
    93. // error 3
    94. // error 3 先于 values 输出 因为 values 需要等待 timeout 异步操作
    95. // Case 4: reject with timeout
    96. promise3 = Promise.resolve(3);
    97. promise2 = 42;
    98. promise1 = new Promise((resolve, reject) => {
    99. setTimeout(reject, 100, "foo");
    100. });
    101. promise = myPromiseAll([promise1, promise2, promise3]);
    102. promise
    103. .then((values) => {
    104. console.log("values", values);
    105. })
    106. .catch((error) => {
    107. console.log("error", error);
    108. });
    109. // error foo
    110. // 参考 [异步回调与Promise](https://ringoer.com/frontend/promise/)
    111. // TODO:手写promise

    作者:奥兰度

    1. /**
    2. *
    3. * @param {Array} promiseAry
    4. * @returns
    5. */
    6. Promise.all = function (promiseAry) {
    7. const resultAry = []
    8. let resolveCount = 0;
    9. let rejectFlag = false
    10. let rejectRes
    11. return new Promise((resolve, reject) => {
    12. const callback = () => {
    13. if (rejectFlag) {
    14. reject(rejectRes)
    15. } else if (resolveCount >= promiseAry.length) {
    16. resolve(resultAry)
    17. }
    18. }
    19. for(let i = 0; i < promiseAry; i++) {
    20. Promise.resolve(promiseAry[i]).then(
    21. (val) => {
    22. resultAry[i] = val
    23. resolveCount++
    24. callback()
    25. },
    26. (err) => {
    27. rejectFlag = true
    28. rejectRes = err
    29. callback()
    30. }
    31. )
    32. }
    33. })
    34. }

    作者:xl

    1. function promiseAll(promises) {
    2. return new Promise((res, rej) => {
    3. const promiseResults = [];
    4. let iteratorIndex = 0;
    5. let fullCount = 0;
    6. for (const item of promises) {
    7. let resultIndex = iteratorIndex;
    8. iteratorIndex += 1;
    9. // 包一层,以兼容非 promise 的情况
    10. Promise.resolve(item).then(value => {
    11. promiseResults[resultIndex] = value;
    12. fullCount += 1;
    13. if (fullCount === ) {
    14. return res(promiseResults);
    15. }
    16. })
    17. .catch(error => {
    18. return rej(error)
    19. })
    20. }
    21. // 处理空 iterator 的情况
    22. if (iteratorIndex === 0) {
    23. res(promiseResults)
    24. }
    25. });
    26. }

    作者:安静

    1. function PromiseAll(iterator) {
    2. const promises = Array.from(iterator);
    3. const length = promises.length;
    4. let index = 0;
    5. const result = [];
    6. return new Promise((resolve, reject) => {
    7. for (let i = 0; i < length; i++) {
    8. promises[i]
    9. .then((res) => {
    10. result[i] = res;
    11. index++;
    12. if (length === index) {
    13. resolve(result);
    14. }
    15. })
    16. .catch((err) => {
    17. reject(err);
    18. });
    19. }
    20. });
    21. }
    22. const promise1 = Promise.resolve('promise1');
    23. const promise2 = new Promise(function (resolve, reject) {
    24. setTimeout(resolve, 2000, 'promise2');
    25. });
    26. const promise3 = new Promise(function (resolve, reject) {
    27. setTimeout(resolve, 1000, 'promise3');
    28. });
    29. PromiseAll([promise1, promise2, promise3]).then(function(values) {
    30. console.log(values);
    31. });

    作者:不更新

    1. const PROMISE_TYPE = "[object Promise]";
    2. const STRING_AND_ARRAY_TYPE = ["[object String]", "[object Array]"];
    3. class Promises {
    4. static all(promises) {
    5. return new Promise(async (resolve, reject) => {
    6. if (
    7. !STRING_AND_ARRAY_TYPE.includes(
    8. Object.prototype.toString.call(promises)
    9. )
    10. ) {
    11. reject("argment is not iterable");
    12. return;
    13. }
    14. const resloveArray = await [...promises].reduce(
    15. (previousValue, currentValue) => {
    16. const isPrmoise =
    17. Object.prototype.toString.call(currentValue) === PROMISE_TYPE;
    18. if (isPrmoise) {
    19. currentValue.then(
    20. (value) => {
    21. previousValue.push(value);
    22. },
    23. (reason) => {
    24. reject(reason);
    25. }
    26. );
    27. } else {
    28. previousValue.push(currentValue);
    29. }
    30. return previousValue;
    31. },
    32. []
    33. );
    34. if (resloveArray.length === promises.length) {
    35. resolve(resloveArray);
    36. }
    37. });
    38. }
    39. }

    作者:
    作者: