Skip to content Skip to sidebar Skip to footer

Resolve Await When Message Arrives

I have some websocket code in JS. I have a message-handling loop like this: socket.addEventListener('message', function (event) { payload = JSON.parse(event.data) method = payl

Solution 1:

something() should be a method that returns a promise() or should be another method that is also notated with async.

functionsomething(){
  returnnewPromise(resolve,reject) {
      //... call your database// thenresolve(theResult)
      // orreject(theError)
  }
}

The async and await for the most part are really just wrappers around promises. The await returns when the promise calls resolve, and throws an exception when the promise calls reject.

Your async function can return another promise; If it returns another value, it gets turned into a resolved promise with that value.

Solution 2:

Now that I understand how promises in Javascript work, here's a working example of a promise that can get woken up from anywhere by calling a function:

wakeup = null;

// returns a promise that will be resolved by calling wakeup()// (could be a list of these or whatever, this is just a simple demo)functionwakeable() {
    returnnewPromise( (resolve) => {
        wakeup = () => { resolve(true); }
    });
}

// demo of waiting and getting woken up:asyncfunctionhandle_event() {
    while (true) {
        console.log("waiting...")
        awaitwakeable(); // returns to event loop hereconsole.log("handle event woke up!");
    }
}

handle_event(); // start in "background"wakeup(); // wake it upsetTimeout(_ => { wakeup(); }, 500); // wake it up again after a delay

What's happening here is that when you call wakeable(), it returns a promise. That promise is constructed with an anonymous function (the one taking resolve as arg); the promise constructor synchronously calls that function, passing it the promise's resolve method. In our case, the function sets wakeup to another anonymous function that calls the original resolve; it's a closure so it has access to that resolve function even when it's called later. Then it returns the new promise.

In this demo, we then await on that promise; that puts the pending promise on a queue, saves the current function state, and returns, like a generator calling yield.

A promise is resolved when its resolve function is called; in this case calling wakeup() calls the promise's internal resolve() method, which triggers any .then methods on the next tick of the Javascript event loop (using the promise queue mentioned above). Here we use await, but .then(...) would work the same way'

So there's no magic; I/O and timeout promises work the same way. They keep a private registry of functions to call when the I/O event or timeout happens, and those functions call the promise's resolve() which triggers the .then() or satisfies the await.

By the way, unlike async in python, leaving a pending promise "open" when the process exits is perfectly fine in Javascript, and in fact this demo does that. It exits when there's no more code to run; the fact that the while loop is still "awaiting" doesn't keep the process running, because it's really just some closures stored in a queue. The event loop is empty, so the process exits (assuming it's in node.js -- in a browser it just goes back to waiting for events).

Post a Comment for "Resolve Await When Message Arrives"