Promise resolves concurrent requests

Foreword: the scene of the second face of Meituan was not made at that time, now to solve this problem well.

Scenario: You are now provided with 10 ids and a request function (the request returns a Promise object), and you are now asked to set a concurrency number (let’s say 3) to achieve the concurrency setting effect.

let request = function(id){
    return new Promise((resolve,reject) = >{
        // A random execution time
        let time = Math.floor(10000*Math.random());
        console.log(` id for${id}Request started, estimated execution time${time/1000}`)
        setTimeout(() = >{
            resolve(id);
        },time)
    }).then((id) = >{
        console.log(` id for${id}Request for logical processing ')
        returnid; })}let idArray = [0.1.2.3.4.5.6.7.8.9.10];
Copy the code

This means that a maximum of three requests are being processed at any one time. (Now I think that’s what it means, this afternoon I think wrong)

Promise version

Set up a pool to hold the promises returned by these requests, send Max (constructor), push the promise into the pool each time, register the then callback, first fetch the promise, then fetch the array ID, and determine the recursion.

function run(){
    // Start the function to execute Max requests directly
    for (let i=0; i<max; i++){ send(request(idArray.shift())); }}function send(promise){
    pool.push(promise);
    promise.then((res) = >{
        console.log(`id${res}The request has been processed and is currently concurrent${pool.length}`);
        // Remove the processed request
        pool.splice(pool.indexOf(promise),1);
        let id = idArray.shift();
        if(id ! = =undefined){
            send(request(id));
        }
    })
}
run();
Copy the code

The then method is used to recursively call the pool.

Async+Promise.race

Ideas: using the async written synchronization code, with the Promise. Race (pool) to control, have the resolve to each of the pool of Promise request (processed), you can continue to send a new request.

async function run(){
    for (let i=0; i<idArray.length; i++){let promise = request(idArray[i]);
        promise.then((res) = >{
            console.log(`id${res}The request has been processed, and the current concurrency is${pool.length}`);
            pool.splice(pool.indexOf(promise),1);
        })
        pool.push(promise);
        // If it is full, it will block
        if (pool.length==max){
            await Promise.race(pool);
        }
    }
}
run();
Copy the code

It’s pretty neat and easy to understand, instead of putting recursion in then.