如何在特定条件下做出承诺解决?

2023-12-08

我是 JavaScript 新手,我真的对 Promise 的文档感到困惑。 我在这里有以下情况,我有很多用户,对于每个用户,我执行一个异步函数,在该函数中我对该用户进行一些计算,并将结果与​​用户一起添加到数组中。根据我从文档中了解到的,我需要在每次执行异步函数时获得一个承诺,并将所有承诺添加到一个承诺列表中,当将结果数组传递给它时,该列表会解析,如下所示:

 someFunction = () => {
   var promises = [];
   users.forEach(user => {
       var promise = asyncFunction(user).callback(callBackValue => {
         // Run some checks and add the user to an array with the result
         if (checksAreGood) {
           usersArray.push({user: user, result: callBackValue});
         }
       });
       promises.push(promise);
   });
   return Promise.all(promises).then(() => Promise.resolve(matches));
 };

问题是:如果我正在遍历的用户数量未知,并且我想将添加到数组中的用户数量限制为 20,当且仅当用户数量超过 20 时,否则添加所有用户。换句话说,当阵列充满 20 个或更少的用户时,解决承诺。 这样做的目的是避免为优化性能而对全部用户执行异步函数。意思是,如果我有 1000 个用户,我希望执行异步函数,直到数组填满到 20 个为止。


第一个只搜索直到找到 20 个用户的解决方案是遍历一个又一个用户 :

 async function someFunction(){
  const results = [];
  for(const user of users){
     const result = await asyncFunction(user);
     // Run some checks and add the user to an array with the result
     if(!someChecksGood) continue;
     results.push(result);
     if(results.length >= 20) break;
  }
  return results;
 }

虽然这工作得“完美”,但它非常慢,因为它一次只处理一个请求。因此,相反的解决方案是一次运行所有请求,并在数组已满时取消它们:

 async function someFunction(){
  const results = [];
  async function process(user){
    const result = await asyncFunction(user);
    if(!someChecksGood || results.length >= 20) return;
    results.push(result);
   }
   await Promise.all(users.map(process));
   return results;
 }

但现在有大量不必要的请求,这些请求随后被丢弃。为了改进这一点,可以通过“分块”请求来结合上述两种方法,这不会减少请求时间,因为数据库一次只能处理一定数量的请求,但好处是我们可以在以下情况下停止处理:数组已满,只有其余的“块”是不必要的,因此平均而言,它应该比上面的两种解决方案更好:

  async function someFunction(){
    //Chunk the users
    const chunks = [], size = 5;
    for(var i = 0; i < users.length; i += size)
      chunks.push( users.slice(i, i + size));
    //the method to create the results:
    const results = [];
    async function process(user){
      const result = await asyncFunction(user);
      if(!someChecksGood || results.length >= 20) return;
      results.push(result);
    }
    //iterate over the chunks:
    for(const chunk of chunks){
      await Promise.all(chunk.map(process));
      if(results.length >= 20) break;
    }
    return results;
 }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在特定条件下做出承诺解决? 的相关文章

随机推荐