javascript并发_限制JavaScript中的并发操作

javascript并发

Usually, the machine that executes our code has limited resources. Doing everything at once might not only hurt, but can also hang our process and make it stop responding altogether.

通常,执行我们代码的机器资源有限。 一次执行所有操作不仅可能会伤害您,而且可能使我们的流程挂起,并使它完全停止响应。

When we want to crawl 100 websites, we should crawl, for example, 5 at once, so that we don’t take up all the available bandwidth. As soon as one website is crawled, the next one is ready to go.

当我们要抓取100个网站时,我们应该一次抓取5个,这样我们就不会占用所有可用带宽。 爬网一个网站后,下一个网站就可以开始使用了。

Generally speaking, all “heavy” operations should be laid out in time. They should not be executed all-at-once, for better performance and to save resources.

一般而言,所有“繁重”的操作都应及时进行。 为了提高性能并节省资源,不应一次执行所有操作。

实作 (Implementation)

If you are familiar with my previous post about implementing promises, then you are going to notice many similarities.

如果您熟悉我以前关于实现promise的文章 ,那么您将注意到许多相似之处。

class Concurrently<T = any> {
  private tasksQueue: (() => Promise<T>)[] = [];
  private tasksActiveCount: number = 0;
  private tasksLimit: number;

  public constructor(tasksLimit: number) {
    if (tasksLimit < 0) {
      throw new Error('Limit cant be lower than 0.');
    }

    this.tasksLimit = tasksLimit;
  }

  private registerTask(handler) {
    this.tasksQueue = [...this.tasksQueue, handler];
    this.executeTasks();
  }

  private executeTasks() {
    while (this.tasksQueue.length && this.tasksActiveCount < this.tasksLimit) {
      const task = this.tasksQueue[0];
      this.tasksQueue = this.tasksQueue.slice(1);
      this.tasksActiveCount += 1;

      task()
        .then((result) => {
          this.tasksActiveCount -= 1;
          this.executeTasks();

          return result;
        })
        .catch((err) => {
          this.tasksActiveCount -= 1;
          this.executeTasks();

          throw err;
        });
    }
  }

  public task(handler: () => Promise<T>): Promise<T> {
    return new Promise((resolve, reject) =>
      this.registerTask(() =>
        handler()
          .then(resolve)
          .catch(reject),
      ),
    );
  }
}

export default Concurrently;

We register a given task by adding it to our tasksQueue and then we call executeTasks.

我们通过将给定任务添加到taskQueue中来注册它,然后调用executeTasks

Now we execute as many tasks as our limit allows us — one by one. Each time adding 1 to our counter called tasksActiveCount.

现在,我们可以按限制执行尽可能多的任务,一个接一个。 每次将1加到我们的称为taskActiveCount的计数器中。

When the executed task finishes, we remove 1 from tasksActiveCount and again call executeTasks.

当执行的任务完成时,我们从taskActiveCount中删除1,然后再次调用executeTasks

Below we can see an example of how it works.

在下面,我们可以看到一个有关其工作方式的示例。

The limit is set to 3. The first two tasks are taking very long to process. We can see the third “slot” getting opened from time to time, allowing the next task in the queue to be executed.

限制设置为3。前两个任务的处理时间很长。 我们可以看到不时打开了第三个“插槽”,从而可以执行队列中的下一个任务。

Always there are three, no more, no less.

总是有三个,不多不少。

You can see the code in the repository.

您可以在存储库中查看代码。

Thank you very much for reading! Can you think of any other way of achieving the same effect? Share them down below.

非常感谢您的阅读! 您能想到其他实现相同效果的方法吗? 在下方分享。

If you have any questions or comments feel free to put them in the comment section below or send me a message.

如果您有任何问题或评论,请随时将其放在下面的评论部分或给我发送消息

Check out my social media!

看看我的社交媒体

Join my newsletter!

加入我的时事通讯

Originally published at www.mcieslar.com on August 28, 2018.

最初于2018年8月28日发布在www.mcieslar.com上。

翻译自: https://www.freecodecamp.org/news/how-to-limit-concurrent-operations-in-javascript-b57d7b80d573/

javascript并发

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值