Promise面试题详解之控制并发

控制并发是 Promise 中比较重要、也比较常见的使用场景之一。 那么在面试中可能会有关于此方面的题目,下面我们来详细讲解一下控制并发的面试题攻略。

什么是并发控制?

并发控制指的是对于某些需要进行并发处理的操作,保证其并发数量的控制。

举个例子,假设我们现在需要爬取若干个网页,但是为了对目标网站造成压力使用单线程轮流爬取的策略并不可取,这时我们就可以用 Promise 来控制每次并发的数量。

Promise 中的限制并发的方法

1. 控制并发的核心方法 promiseLimit()

下面的程序代码中 corePromise() 是一个返回 Promise 的函数,执行上限设置为 limit,即 limit 个请求并发,拿到结果后将结果存到 results 中,并在所有请求完毕后一起返回。

const promiseLimit = async (arr, corePromise, limit) => {
  let results = [],
      index = 0;
  const doing = (task) => {
     return new Promise(resolve => {
        const i = index++;
        Promise.resolve().then(async () => {
          results[i] = await corePromise(task);
        }).finally(() => {
          resolve();
        });
     })
  };
  let promises = arr.map(task => doing(task));
  await Promise.all(promises);
  return results;
};

promises 对单个任务的并发限制(限制单个任务只有在结果返回后才开始下一个任务)使用自己暴露出的接口(例如:doSomethingAsync(),也可以是 Promise 的实例方法)的方式实现,即通过 Promise.resolve().then() 来控制每次并发的数量。返回值 results 是所有任务执行完毕返回的数据集合。

2. 示例

下面使用一个获取网页的异步函数getPage() 来演示 promiseLimit() 的应用。

若我们有一个数组 urls,需要一次性并发请求 3 个网页,且请求的代码逻辑都一样,则可以使用如下代码来控制并发数量:

const task = async url => {
  const html = await getPage(url);
  return html;
};
const urls = ['url1', 'url2', 'url3', 'url4', 'url5', 'url6'];
const res = await promiseLimit(urls, task, 3);

上述代码中,遍历 urls 数组,每个 url 都会发送请求,但每次的并发数量将不会超出 3 个。

Promise 中的完整示例

下面给出一个完整的示例,该例子演示如何获取 30 条《红楼梦》的不同章节,限制并发数量为 5:

1. 获取章节名数组

async function fetchChapterTitles() {
  const res = await got.get('https://www.shicimingju.com/book/hongloumeng.html');
  // 利用正则匹配出所有章节链接
  const chapterLinks = res.body.match(/(?<=<a href=")\/chapter\/[^"]+(?=">)/g);
  const chapterTitles = await promiseLimit(
    chapterLinks.slice(0, 30), // 我们只需要前 30 个章节
    async (link) => {
      const pinyin = link.split('/').slice(-1)[0];
      const url = `https://www.shicimingju.com/chapter/${pinyin}.html`;
      const res = await got.get(url);
      const title = res.body.match(/(?<=<h1>)[^<]+/g);  
      return `[第${title[0]}回]`;
    },
    5 // 最多同时 5 个并发请求
  );
  return chapterTitles;
}

2. 运行程序

将上述代码保存到一个 .js 文件中,并运行如下程序:

const titles = await fetchChapterTitles();
console.log(titles);

执行结果将会输出《红楼梦》前 30 章的章节名称。

以上就是 Promise 面试题详解之控制并发的攻略。对于面试官提及的相关问题,可以根据上述方法进行回答,同时要注意在实现中保持代码的规范和正确性。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Promise面试题详解之控制并发 - Python技术站

(0)
上一篇 2023年5月16日
下一篇 2023年5月16日

相关文章

  • python的多线程原来可以这样解

    下面是详细讲解“Python的多线程原来可以这样解”的完整攻略。 什么是多线程? 多线程是指一个进程(程序)中包含多个并发执行的流,每一个流都称为一个线程(Thread),多线程可以将程序中的计算密集型和I/O密集型工作分别交给不同的线程负责,从而提高程序的并发性和效率。 Python中的多线程 Python中的多线程是通过操作系统的线程实现的,Python…

    多线程 2023年5月17日
    00
  • 浅谈Redis高并发缓存架构性能优化实战

    浅谈Redis高并发缓存架构性能优化实战 一、前言 随着互联网的发展,访问量的激增,如何提高网站的响应速度,增加网站的并发能力成为了大家关注的热点。而Redis作为高性能缓存数据库,成为了缓存业务的首选。 在实际开发中,Redis高并发缓存架构的性能优化是非常重要的,本文将结合实战经验,浅谈Redis高并发缓存架构性能优化的几个方面。 二、Redis高并发缓…

    多线程 2023年5月17日
    00
  • GoLang并发机制探究goroutine原理详细讲解

    GoLang并发机制探究goroutine原理详细讲解 什么是goroutine goroutine 是Go语言中的一种轻量级线程,能够在用户态(User Space)进行创建和销毁,不需要操作系统提供的线程管理和调度,因此比传统线程的创建、销毁和轮转开销更小,同时能够高效地利用多核CPU性能。 Go语言中的协程(goroutine)有着更加灵活的调度和更少…

    多线程 2023年5月17日
    00
  • C#多线程Thread使用示例详解

    下面我将详细讲解“C#多线程Thread使用示例详解”的完整攻略。 C#多线程Thread使用示例详解 什么是多线程? 在计算机里,线程是一个可执行的代码片段。我们可以将线程视为一堆计算机程序指令。一个程序可以同时运行多个线程。多线程技术可以让计算机同时处理多项任务,从而更加高效。 如何使用多线程? 在C#中,可以使用Thread类来实现多线程技术。具体使用…

    多线程 2023年5月17日
    00
  • Java基础之多线程

    Java多线程的基础知识 在 Java 编程中,多线程是非常常见的技术,多线程的使用可以在提高程序并发性能的同时,也增加了程序的复杂度,因此学好多线程技术对于 Java 开发人员来说是非常重要的。 1. 创建线程 在 Java 中创建一个线程有两种主要方法: 1.1. 实现 Runnable 接口 Runnable 接口是 Java 多线程中的一个基本接口,…

    多线程 2023年5月17日
    00
  • python并发和异步编程实例

    针对“python并发和异步编程实例”的完整攻略,本文将分为以下几个部分进行说明: 并发编程和异步编程的概念解释 并发编程实例演示 异步编程实例演示 总结和建议 1. 并发编程和异步编程的概念解释 在开始讲解并发编程和异步编程实例之前,我们需要先理解这两个概念。 并发编程是指同时执行多个任务,不一定要在同一时刻,但一段时间内它们是交替执行的。 异步编程是指仅…

    多线程 2023年5月16日
    00
  • 在Go中构建并发TCP服务器

    针对“在Go中构建并发TCP服务器”的完整攻略,我为您提供以下内容: 1. 概述 在Go语言中,可以使用标准库net和net/http来轻松地构建TCP和HTTP服务器。在本文中,我们将介绍如何使用net库来构建并发TCP服务器。下面,将逐步介绍TCP服务器的实现步骤。 2. 步骤 步骤1:导入必要的包 既然我们要使用Go语言中的net库,因此在首个步骤中,…

    多线程 2023年5月17日
    00
  • Java多线程面试题(面试官常问)

    下面就来详细讲解一下“Java多线程面试题(面试官常问)”的完整攻略。 一、题目解析 在多线程的面试过程中,常会遇到关于线程的基本概念、线程的安全性、线程池的使用等方面的问题。常见的面试题目包括: 1. 什么是线程? 线程是指操作系统能够进行运算调度的最小单位,是程序执行过程中的一个执行单元。 2. 什么是线程安全? 线程安全是指在多线程并发的情况下,共享的…

    多线程 2023年5月16日
    00
合作推广
合作推广
分享本页
返回顶部