1

In my JS application I need to download multiple(hundreds) images at certain event. Once the event happens all images are being pun in queue and downloaded. Since Chrome and other browsers only allow limited number of concurrent downloads only 5 or so are being downloaded at the same time. the rest are put in queue.

My problem is that while the images are being downloaded user may raise an event that will require a higher priority download. But it is being put in the end of queue and waits until lower priority stuff gets downloaded.

I decided to implement my own queue where I can control the priority of my downloads. Currently when the event is raised to download low-pr images hundreds of fetch promises are being immediately created and resolved when the images are downloaded.

Instead of returning a fetch promise(that will get executed right away) i want to return a promise that can be resolved at a later time. Then pass this promise to my queuing function and let it decide when to resolve it.

This is how a call is initiated:

static addCall(params) {
let returnPromise = new Promise((resolve, reject) => { });

let CallParams = {
    Promise: returnPromise,
}

//push call in a queue
Backend.CallQueue.push(CallParams);

//run queue
Backend.enforceQueue();

return returnPromise;
}

This is my queue handling:

static ConcurrentCallsLimit = 3;
static CallQueue = [];
static RunningCalls = [];

static enforceQueue() {
    //If currently running less concurrent calls then a maximum allowed - add more
    if (Backend.RunningCalls.length < Backend.ConcurrentCallsLimit) {
        for (let i = 0; i < Backend.ConcurrentCallsLimit - Backend.RunningCalls.length; i++) {
            let nextCall = Backend.CallQueue.shift();
            if (nextCall) {
                //push in line & run
                Backend.RunningCalls.push(nextCall);
                Backend.runCall(nextCall);
            }                
        }
    }
}

And a RunCall method: (trying to resolve a promise that is passed as parameter)

static runCall(CallParams){
  fetch("path", {...})
     .then((resp)=>{
         CallParams.Promise.resolve(resp);  //this will not work :(
     });
}

//CallParams.Promise.resolve is not a function
AnKing
  • 1,994
  • 6
  • 31
  • 54
  • Your problem is in this line `let returnPromise = new Promise((resolve, reject) => { });` i'm not sure what that supposed to mean, but the value of `returnPromise` is a `promise` that is never resolved, and all you can call on a promise is `then()` `catch()` and `finally()` – Rainbow Apr 19 '19 at 19:17
  • @ZohirSalak I'm just creating a blank promise there, there is an intention to resolve it outside the functon scope – AnKing Apr 19 '19 at 19:19
  • 1
    You're creating a never resolved Promise, Promises resolves themselves that's why the constructor requires a function resolver, you can't resolve a promise from the outside, callbacks seem much reasonable for what you're trying to do here – Rainbow Apr 19 '19 at 20:26
  • 1
    A Promise represents an asynchronous activity that is already underway, therefore if you have promises it's too late to prevent the downloads. From what I understand, you are queueing promises and expecting then to exercise control over them. You can't, at least not in the way you want. Instead queue data or executables, whatever you need to initiate a download, from which a promise will arise. – Roamer-1888 Apr 19 '19 at 23:32
  • "*a promise that can be resolved at a later time*" - don't do that. Just make a function that can be called at a later time, returning a promise. If you need to get the promise right away for some reason, have a look at [Promises for promises that are yet to be created](https://stackoverflow.com/q/37426037/1048572) – Bergi Apr 20 '19 at 07:56

0 Answers0