如何根据特定条件解决承诺? [英] How to make a promise resolve with a specific condition?

查看:63
本文介绍了如何根据特定条件解决承诺?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am new to JavaScript and I really got confused by the documentation about promises. I have the following case here where I have a punch of users and for each user I execute an async function in which I do some calculations on that user and add the result along with the user to an array. From what I understood from the documentation that I need to get a promise for each time the async function is executed and add all the promises to a list of promises that resolve when the resultant array is passed to it as following:

 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个用户或更少时,解析promise。
这样做的目的是避免为优化性能而为整个用户执行异步函数。意味着,如果我有1000个用户,我希望执行异步函数,直到数组满为20。

Question is: if the number of the users I am traversing is unknown and I want to limit the number of users added to the array to 20 if and only if the number of users are more than 20 otherwise add all the users. In other words, resolve the promise when the array is full of 20 users or less. The purpose for this is to avoid executing the async functions for the whole number of users given to optimize performance. Means, if I have 1000 users I want the async function to be executed until the array is full to 20 only.

推荐答案

第一个解决方案,只搜索到找到的20个用户将遍历一个又一个用户

The first solution which only searches until 20 users where found would be to traverse one user after another :

 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;
 }

虽然这是完美的,但它只是处理一个请求而非常慢一次。所以相反的解决方案是一次运行所有请求并在阵列已满时取消它们:

While this works "perfect", its quite slow as it only processes one request at a time. So the opposite solution would be to run all requests at a time and cancel them if the array is already full:

 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;
 }

但现在有大量不必要的请求,之后会被丢弃。为了改善这一点,可以通过分块请求来结合上述两种方法,这不应该减少请求时间,因为dbs一次只能处理一定数量的请求,但好处是我们可以在停止时处理数组已满,只有chunk的其余部分是不必要的,所以平均来说它应该优于上述两种解决方案:

But now there is a high number of unneccessary requests, that are discarded afterwards. To improve this, one could combine both approaches above by "chunking" the requests, which should not decrease request time that much as dbs can only process a certain amount of requests at a time, but the good thing is that we can stop processing when the array is full, and only the rest of the "chunk" is unneccessary proccessed, so in average it should be better than both solutions above:

  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;
 }

这篇关于如何根据特定条件解决承诺?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆