Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I limit angular $q promise concurrency?

How do I do something like $q.all but limiting how many promises are executed concurrently?

My question is just like How can I limit Q promise concurrency?

I want no more than 5 process spawned at a time

The accepted answer for that other question is a library written for promise wrapped to work with Q. But I'm interested specifically in a solution for Angular's $q rather than for Q.

Background: The problem being solved:
I have a bunch of files to download in 2 steps: a) Get URL b) download file.
The browser limits how many files can be retrieved concurrently, so when the straightforward use of promises with $q.all fires off all the downloads, only
N happen right away, e.g. 6 in Chrome, while the rest are delayed. (see Max parallel http connections in a browser?)
Problem is that the URLs have expiry, so by the time the browser executes the N+1thfile download, the URL is no longer valid.
So I want to do something like throttled.all(6, promises) rather than $q.all(promise)

like image 452
Daryn Avatar asked Oct 30 '22 13:10

Daryn


1 Answers

If the resolving of 'all' Promises is irrelevant (like you are updating some Elements on the page and you don't care if it's progressive and not in one 'whoosh') I have created a simple TaskQueue Service. It will not wait for all Promises to be resolved but rather it will process all added Promises/Functions/Tasks it gets and with a max. concurrency of a configured limit value.

As I only found this and some other StackOverflows not helping with my problem I had. So I now give something back to the community I guess. Hope it helps somebody.

It uses modern JS stuff like const and lambda expressions, but you may simply let it compile down from a precompiler like babel if you just want the 'old' stuff.

https://gist.github.com/Blackskyliner/8b1bafed326044fa4f8b1ba2627d1117

It just simply processes its queue after Tasks, which are just anonymous functions, returning a promise or value, are added. It will adhere to a configurable 'maxConcurrentTasks' variable on the service.

If the Task returns a promise which returns a promise and so on it will always use the initial 'slot' within the queue. So it will free the 'slot' for an other added Task after the whole Task Promise chain is resolved (or rejected).

like image 170
Blackskyliner Avatar answered Nov 14 '22 01:11

Blackskyliner