承诺池JavaScript leetcode 2636
#javascript #前端 #leetcode #面试

给定一系列异步函数functions和池限制n,返回异步函数promisePool。当所有输入函数解决时,它应该返回解决的承诺。

池限制被定义为可以立即挂起的最大承诺数量。 promisePool应开始执行尽可能多的功能,并在旧承诺解决时继续执行新功能。 promisePool应该执行functions[i],然后functions[i + 1],然后是functions[i+2]等。

例如,如果n = 1,PromisePool将一次在系列中执行一个功能。但是,如果n = 2,它首先执行两个函数。当两个函数解决方案中的任何一个中的任何一个时,都应执行第三个功能(如果可用),依此类推,直到没有函数可以执行为止。

您可以假设所有功能永远不会拒绝。 PromisePool返回解决任何价值的承诺是可以接受的。

示例1:
输入:

functions = [
       () => new Promise(res => setTimeout(res, 300)),
       () => new Promise(res => setTimeout(res, 400)), 
       () => new Promise(res => setTimeout(res, 200))
]
n = 2

输出: [[[300,400,500],500]

说明:

传递了三个功能。它们分别入睡300ms,400ms和200ms。

他们分别以300ms,400ms和500ms的速度解析。返回的承诺以500毫秒为基础。

在t = 0时,执行了第一个两个函数。达到2的池尺寸限制。

在t = 300时,第一个函数解析,并且执行第三函数。游泳池尺寸为2。

在t = 400时,第二函数解析。没有什么可执行的。游泳池尺寸为1。

在t = 500时,第三函数解析。池大小为0,所以返回的承诺也可以解决。

示例2:
输入:

functions = [
    () => new Promise(res => setTimeout(res, 300)),
    () => new Promise(res => setTimeout(res, 400)),
    () => new Promise(res => setTimeout(res, 200))
] 
n = 5

输出: [[[300,400,200],400]

说明:

三个输入承诺分别为300ms,400ms和200ms。

返回的承诺以400ms的方式解决。

在t = 0时,所有3个功能均已执行。池极限从未满足。

在t = 200,第三函数解析。游泳池尺寸为2。

在t = 300时,第一个函数已解决。游泳池尺寸为1。

在t = 400时,第二函数解析。泳池的大小为0,所以重新付出的承诺也可以解决。

示例3:
输入:

`
functions = [
()=>新承诺(res => settimeout(res,300)),
()=>新承诺(res => settimeout(res,400)),
()=>新承诺(res => settimeout(res,200))
]

n = 1
`

输出:[[[300,700,9001,900]

说明:

三个输入承诺分别以300ms,700ms和900ms的速度解决。返回的承诺以900ms的方式解决。

在t = 0时,执行了第一个函数。游泳池尺寸为1。

在t = 300时,第一个函数解析和第二个功能被执行。游泳池尺寸为1。

在t = 700时,第二个功能解析和第三函数被执行。游泳池尺寸为1。

在t = 900时,第三函数解决。池大小为0,因此退回的承诺可以解决。

约束:

0 <= function.length <= 10

0 <= n <= 10

直觉:

问题围绕以指定的池限制以受控方式执行一组给定的异步功能。目标是在池限制允许的同时同时执行尽可能多的函数,同时确保总体执行顺序遵循输入函数的顺序。

方法:

  • PromisePool函数用两个参数定义:异步函数的一个数组和代表池限制的整数n。

  • 该功能返回承诺。这是一种异步功能,它利用异步/等待语法并将其用于其异步操作。

  • 在返回的承诺中,定义了辅助功能。此功能负责管理功能的执行和池大小。

  • 检查了递归的基本情况:如果索引大于或等于功能的长度,并且没有诺言(Inprogress === 0),则表示所有功能均已执行。在这种情况下,主要承诺将决定完成。

  • 在辅助函数内部,使用一个while循环来并行执行池限制n。它检查了池中是否有空间(Inprogress

  • 满足循环条件时,将增量iNPOGRESS计数器,并使用.Then()执行索引处的当前函数。当该函数的承诺解析时,启动计数器会减小,并且辅助函数被递归地称为。这样可以确保一旦一个函数完成,就可以启动另一个功能。

  • 在辅助功能之外,执行是通过首次调用助手功能来启动执行。

代码:

`
/**

  • @param {function []}函数
  • @param {number} n
  • @return {function}
    */
    // tc:o(functions.length)
    var proMisePool = async函数(functions,n){
    返回新的承诺((lesolve)=> {
    让InProgress = 0,index = 0;
    功能助手(){
    //基本案
    if(index> = functions.length){
    if(inprogress === 0)resolve();
    返回;
    }

    while(inprogress inprogress ++;
    functionsindex++.then(()=> {
    inprogress-; <​​br> 助手();
    });
    }
    }
    助手();
    });
    };

/**

  • const sleep =(t)=>新承诺(res => settimeout(res,t));
  • PromisePool([(()=>睡眠(500),()=>睡眠(400)],1)
  • 。然后(console.log)// 900ms之后 / ` **时间复杂性:*

此代码的时间复杂性为o(functions.length),其中函数。长度表示输入数组中的函数数量。这是因为每个函数在段循环内执行一次,并且While循环通过数组中的所有函数迭代。

空间复杂性:

此代码的空间复杂性是o(1),这是恒定的空间复杂性。这是因为代码的内存使用情况不会随输入大小或任何递归深度而生长。

查看视频解决方案:

希望您会发现有用,如果是,请给出一个。