2

I'm relatively new to Promises in Javascript, but have recently fell in love with their elegance, particularly in the Bluebird library.

This is probably a newbie question, but how could I convert a normally-synchronous function to run asynchronously? If I, for example, wanted to compute Math.random()*RANGE thirty times in-parallel, how exactly could I do that with promises (in either Q or Bluebird)?

4
  • 1
    If you want it to actually run asynchronously (so other code can run interwoven with its execution), you would either have to use setTimeout() to schedule consecutive chunks of execution or use webWorkers to actually set up another thread. You can see the core mechanism here for executing chunks of work with setTimeout() which could then just return a promise and then resolve that promise when the work was done. Commented Jul 19, 2014 at 1:00
  • 1
    I presume you also know that computing 30 random numbers takes very little time and doesn't really need to be dealt with in an async way and in fact may perform worse by adding overhead of doing it async - perhaps this is only an example you're using? Commented Jul 19, 2014 at 2:16
  • @jfriend00 I was just using the Math.random as an example, but I like the idea of wrapping stuff in a setTimeout(fn,0) to force asynchonity. Commented Jul 19, 2014 at 16:18
  • i think your question will receive much more responses if you would give another example (not Math.random): i have a NodeJS app with Bluebird promises and want to run 30 queries (let's say i have Redis, Postgres and S3 subsystems - and i need to run 10 queries in each). All queries are independent, and instead of waiting for T1 + T2 + .. + T30 seconds, i want to wait for max(T1, T2 .., T30) + small_overhead_of_parallelism. So how can I achieve something like this with Bluebird API the most elegant way? Commented Oct 27, 2022 at 2:13

2 Answers 2

2

First off, promises won't help you make code run in parallel. They are a tool for running other code when your task is done or coordinating this task with other tasks. But making your current code run in parallel with other code has nothing to do with promises.

Second off, there's little advantage (and a lot of complication) to taking a synchronous task and trying to make it work more like an asynchronous tasks unless it is so long running that it interferes with the responsiveness of other operations. Computing a set of random numbers is unlikely to be that long a running task.

If you truly want parallel execution in a browser, you would have go use WebWorkers which is the only way to create an truly independent execution thread in browser-based javascript. Other than WebWorkers, javascript in a browser is single threaded so there is no parallel execution. It is possible to execute small chunks of code on successive setTimeout() calls which will interweave your code execution with other things going on in the browser and can allow other browser tasks to remain responsive while running another long running task.

You can see an example of processing a large array in chunks using setTimeout() here Best way to iterate over an array without blocking the UI to allow other things to run in between chunks of processing. Promises could be added to something like this as a method of managing the completion of the task or managing its coordination with other tasks, but promises don't actually help you make it work in chunks.

Sign up to request clarification or add additional context in comments.

1 Comment

The setTimeout idea worked perfectly. I'm not actually using it for Math.random, but I just thought of it as the first synchronous code that popped into my brain.
2

You cannot. Promises don't "make code parallel", they just provide a better abstraction for asynchronous code - they don't have more power than callbacks.

A synchronous code will always be executed synchronously, and is - due to JavaScript's single-threaded nature - not parallelisable. Even if you give it a callback whose execution is deferred by the use of an actually async function, that will just defer the callback to a later event loop slice, but not make your synchronous task execute in parallel to anything else - and won't make it execute faster either. It only might help to break up long-running code into chunks (see here or here) which can make an app feel faster.

What you can do is execute the code on another thread (WebWorker, node cluster, …) and use events to pass the results back. For those events, you could code a nice promise abstraction; but seriously - the overhead of threads is much too large for just generating 30 random numbers.

6 Comments

This is the correct answer. The key thing here is the difference between concurrency which means execution is interleaved and parallelism which means things run together. It's worth mentioning that everything in JavaScript is synchronous except host functions.
I'm asking as the Async module for Node has a .parallel function, to run several functions in that. I guess what I'm asking is how to replicate that in promises.
@jfriend00: That's in the last paragraph of my answer already :-)
Perhaps I didn't phrase my question as well as I should have; the issue is that I didn't want some synchronous operations on an array to be blocking. I know you can't really do true parallelism in JS without something like a Web Worker.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.