xgqfrms™, xgqfrms® : xgqfrms's offical website of cnblogs! xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!

JavaScript execute asynchronous functions in Parallel with count and Promise All In One

JavaScript execute asynchronous functions in Parallel with count and Promise All In One

JavaScript 使用 count 和 Promise 并行执行异步函数

errors


function promiseAll<T>(functions: Fn<T>[]): Promise<T[]> {
  return new Promise((resolve, reject) => {
    let temp = [];
    for(let [i, func] of Object.entries(functions)) {
      console.log(`✅ i =`, i);
      console.log(`✅ func =`, func);
      (async (index) => {
        await func().then(value => {
          temp[index] = value;
          console.log(`❓ index =`, index);
          console.log(`value =`, value);
          console.log(`temp =`, temp);
          if(temp.length === functions.length) {
            return resolve(temp);
          }
          // temp = (3) [4, empty, 16] ❌
          // if(temp.length === functions.length && !temp.some(v => Object.prototype.toString.call(v) === '[object Promise]')) {
          //   return resolve(temp);
          // }
        }).catch(err => {
          return reject(err);
        });
      })(i);
    }
  });
};


function promiseAll<T>(functions: Fn<T>[]): Promise<T[]> {
  return new Promise((resolve, reject) => {
    let temp = [];
    let index = 0;
    for(let [i, func] of Object.entries(functions)) {
      console.log(`✅ i =`, i);
      // console.log(`func =`, func);
      func().then(value => {
        // temp[i] = value;
        temp[index] = value;
        index += 1;
        // temp.push(value);
        console.log(`❓ i =`, i);
        // index 0 twice bug ❌ 覆盖 bug
        // 💩 temp = [ 4, <1 empty item>, 16 ]
        console.log(`value =`, value);
        console.log(`temp =`, temp);
        // value = 16
        // temp = [ 4, <1 empty item>, 16 ] 2
        // setTimeout 时间先后顺序 bug ❌
        if(temp.length === functions.length && !temp.some(v => Object.prototype.toString.call(v) === '[object Promise]')) {
          return resolve(temp);
        }
        // setTimeout 时间先后顺序 bug ❌
        // setTimeout(() => {
        //   if(temp.length === functions.length) {
        //     return resolve(temp);
        //   }
        // }, 0);
      }).then(() => {
        // setTimeout 时间先后顺序 bug ❌
        // console.log(`temp =`, temp);
        // if(temp.length === functions.length) {
        //   return resolve(temp);
        // }
      }).catch(err => {
        return reject(err);
      }).finally(() => {
        // setTimeout 时间先后顺序 bug ❌
        // console.log(`temp =`, temp);
        // if(temp.length === functions.length) {
        //   return resolve(temp);
        // }
      });
      // if(temp.length === functions.length) {
      //   return resolve(temp);
      // }
      // let id = setInterval(() => {
      //   if(temp.length === functions.length && !temp.some(v => Object.prototype.toString.call(v) === '[object Promise]')) {
      //     clearInterval(id);
      //     return resolve(temp);
      //   }
      // }, 0);
    }
  });
};

function promiseAll() {
  return new Promise((resolve, reject) => {
    let temp = [];
    for(let [i, func] of Object.entries(functions)) {
      // console.log(`i =`, i);
      // console.log(`func =`, func);
      func().then(value => {
        console.log(`value =`, value);
        temp[i] = value;
        console.log(`temp =`, temp, i);
      }).catch(err => {
        return reject(err);
      });
    }
    // ❌ bug
    console.log(`temp ? =`, temp);
    setTimeout(() => {
      console.log(`temp =`, temp);
      if(temp.length === functions.length) {
        return resolve(temp);
      }
    }, 0);
  });
};

问题剖析

type Fn<T> = () => Promise<T>

function promiseAll<T>(functions: Fn<T>[]): Promise<T[]> {
  return new Promise((resolve, reject) => {
    let temp = [];
    let count = 0;
    for(let [i, func] of Object.entries(functions)) {
      func().then(value => {
        temp[i] = value;
        count += 1;
        // count ✅
        // if(count === functions.length) {
        //   return resolve(temp);
        // }
        // bug ❌
        // 使用 temp[i] = promise 赋值的时候 temp 长度就具有了;
        // 但是此时 promise 可能还没有返回结果,从而导致出现 empty 值的bug 
        // temp = (3) [4, empty, 16] ❌
        // i = 2 时候,temp 长度为 3, 但是此时 temp[1] 的 setTimeout 还没有返回结果,故出现 empty bug ❌
        if(temp.length === functions.length) {
          return resolve(temp);
        }
      }).catch(err => reject(err));
    }
  });
};

image

solutions

type Fn<T> = () => Promise<T>

function promiseAll<T>(functions: Fn<T>[]): Promise<T[]> {
  return new Promise((resolve, reject) => {
    let temp = [];
    let count = 0;
    for(let [i, func] of Object.entries(functions)) {
      func().then(value => {
        temp[i] = value;
        count += 1;
        // count ✅
        // 使用 count 避免出现 empty 返回值情况 ✅
        if(count === functions.length) {
          return resolve(temp);
        }
      }).catch(err => reject(err));
    }
  });
};

image

demos

LeetCode 2721. Execute Asynchronous Functions in Parallel

function promiseAll() {
  return new Promise((resolve, reject) => {
    let temp = [];
    let count = 0;
    for(let [i, func] of Object.entries(functions)) {
      func().then(value => {
        temp[i] = value;
        count += 1;
        // count ✅
        // 使用 count 避免出现 empty 返回值情况 ✅
        if(count === functions.length) {
          return resolve(temp);
        }
      }).catch(err => reject(err));
    }
  });
};

const functions = [() => new Promise(resolve => setTimeout(() => resolve(4), 50)), () => new Promise(resolve => setTimeout(() => resolve(10), 150)), () => new Promise(resolve => setTimeout(() => resolve(16), 100))];

promiseAll(functions).then(console.log);

image

https://leetcode.com/problems/execute-asynchronous-functions-in-parallel/description/?envType=study-plan-v2&envId=30-days-of-javascript

refs

https://leetcode.com/problems/execute-asynchronous-functions-in-parallel/solutions/5194050/leetcode-promiseall/

https://leetcode.com/problems/execute-asynchronous-functions-in-parallel/solutions/3888598/promises-are-confusing-i-wrote-some-notes-down-for-you/



©xgqfrms 2012-2025

www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!

原创文章,版权所有©️xgqfrms, 禁止转载 🈲️,侵权必究⚠️!


posted @   xgqfrms  阅读(5)  评论(2编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
历史上的今天:
2023-05-21 Top 100 GitHub Users in China All In One
2023-05-21 js number format All In One
2023-05-21 如何破解网页使用 MutationObserver 禁用修改 DOM 功能 All In One
2022-05-21 Swift if & if let & guard let All In One
2022-05-21 Xcode clear cache All In One
2022-05-21 SwiftUI ViewModel error All In One
2022-05-21 Xcode show color picker in code All In One
点击右上角即可分享
微信分享提示