52

Recently, I have been seeing the concept of Promises being implemented in AngularJS and JQuery.

I have seen the implementation of a Futures in Java as in code below, however this requires concept of thread pools to be present in language/platform. However, there is no such threading concept in Javascript. How are Promises in Javascript implemented then ?

public class Futures1 {

    private static final ExecutorService pool = Executors
            .newFixedThreadPool(10);

    public static void main(String[] args) {

        Future<String> contentsFuture = null;
        try {
            contentsFuture = startDownloading(new URL("http://www.example.com"));
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        // other computation
        try {
            final String contents = contentsFuture.get();
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }

    }
    
    public static Future<String> startDownloading(final URL url) {
        return pool.submit(new Callable<String>() {
            @Override
            public String call() throws Exception {
                try (InputStream input = url.openStream()) {
                    return IOUtils.toString(input, StandardCharsets.UTF_8);
                }
            }
        });
    }
}
dimitar.bogdanov
  • 387
  • 2
  • 10
Madhur Ahuja
  • 22,211
  • 14
  • 71
  • 124
  • Not sure I get the question, but javascript is generally single threaded, with the exception of certain native methods, such as ajax, webworkers, timeouts, websockets and an increasingly number of new methods including Promises. In other words, native methods doesn't neccessarely have to abide by the rules of single threadyness – adeneo Aug 01 '14 at 14:53
  • 7
    Javascript is non-synchronous using events -- events do not require threads but can easily implement promises. Events existed in the single core 8088, at the time they were called "hardware interrupts" – Hogan Aug 01 '14 at 14:53
  • 3
    Concurrency != Parallelism. As simple as that, code is interleaved. – Benjamin Gruenbaum Aug 01 '14 at 17:30
  • 7
    Think of it this way - promises do not *provide* asynchronism, but are a syntactic convenience for *handling* asynchronism provided by other means. – Roamer-1888 Aug 02 '14 at 11:51
  • 4
    Promise are [implemented in terms of callbacks](http://stackoverflow.com/a/22562045/1048572). So how are callbacks asynchronous? Well, [that's a different question](http://stackoverflow.com/q/22286887/1048572) – Bergi Aug 02 '14 at 14:20
  • Promises work only because Javascript is an asynchronous (callbacks) language by nature. So you might actually be asking how javascript implements this asynchronous mechanism on a single thread. Here are some answers: [Answer1](https://stackoverflow.com/questions/20916547/in-javascript-how-do-asynchronous-callbacks-work-in-a-single-thread) [Answer2](https://softwareengineering.stackexchange.com/questions/194580/how-does-javascript-code-become-asynchronous-when-using-callbacks) – TchiYuan Aug 01 '14 at 15:05

3 Answers3

54

Promises were invented to help manage asynchronous operations. Promises themselves do not need threads in order to do that. They are objects that essentially provide bookkeeping for asynchronous operations - keeping state flags, result values and listeners for a state transition. These are all things that can easily be done with regular single threaded Javascript.

So, as long as you have asynchronous operations (however those operations are implemented), you can benefit from promises and don't need threads to implement them.

What it looks like you are seeing in your Java code is code that helps run regular tasks in a separate thread (to give synchronous operations some asynchronous-type behavior). That is not what promises do. So, if you already have asynchronous operations in your environment, you would not need this type of code in order to use promises.

Examples of asynchronous things in Javascript are pretty much anything that you register an interest in and the actual event occurs some time in the future and other code can run before that event fires. In a browser's Javascript environment, this includes things like setTimeout(), keyboard events, mouse events, ajax completion callbacks, etc... These are all asynchronous events. You register an interest in them (by registering an event listener or passing a callback to some function). Internal to the Javascript implementation, there are likely threads that are making these asynchronous events work, but those threads do not need to be exposed to the programmer directly for the asynchronous functionality to be there. For example, see this post for how Javascript manages to run ajax calls in the background while other Javascript things are running. All you need to know is that your callback function will be called some indeterminate time in the future.

So, in Javascript, promises are used to manage the asynchronous operations that are already present in your environment. They are not used to make non-async things become async (you would need threads in order to do that).

Keep in mind that promises themselves are just monitoring tools, used to monitor existing asynchronous operations. Promises are not actually asynchronous themselves except for .then() which can be implemented with a built-in API such as setTimeout() or setImmediate() or nextTick(). Promises do not need their own native code or threads. In fact, you can write a promise implementation in plain, single threaded Javascript if you want.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • 1
    Do you have a good resource/reference for that last sentence? Interested in looking more into that – aks. May 12 '17 at 16:30
  • 1
    @aks. - There are numerous 3rd party promise libraries such as [Q](https://github.com/kriskowal/q) and [Bluebird](https://github.com/petkaantonov/bluebird) that are written in just Javascript. Bluebird is my promise library of choice. – jfriend00 May 12 '17 at 16:37
  • I meant articles about implementing your own. I already swear by bluebird :) – aks. May 12 '17 at 21:36
  • 2
    @aks. - I'm not sure what you're looking for. You can just go look at the source code of both Q and Bluebird at the links in my previous comment. It's all there how to do it. In a nutshell, a Promise library is just a notification system that follows some standardized rules. You register an interest in a certain event and it calls your callback if/when that event occurs. – jfriend00 May 12 '17 at 22:01
6

The browser-written native code underneath the JavaScript layer tends to have threads implemented very neatly. As it turns out, that's usually all you need. Promises tend not to be needed for performing actual computation work in JavaScript (although workers make that easier) but for loading outside resources, and getting callbacks when they're done. JS Promises just assign callbacks to those functions like "image.onLoad" and check whether to notify another function.

Hogan may have summarized it best - event-based programming.

Katana314
  • 8,429
  • 2
  • 28
  • 36
2

I think that Roamer-1888's comment in reply to the OP may be the key to distilling the information in other answers into something simple to understand.

Think of it this way - promises do not provide asynchronism, but are a syntactic convenience for handling asynchronism provided by other means. - Roamer-1888

JS is single-threaded, but the environments JS is running in can take advantage of other threads. To use the browser as an example: JS has access to web APIs (fetch, for example) that allow it, via the browser engine, to perform work outside of the single-threaded JS environment, whether that be a network request, something handled by a web worker, whatever. Promises simply keep track of these operations and receive their results when they've finished.

Andrew
  • 3,825
  • 4
  • 30
  • 44