0

All async/await code can be translated to Promises, or other constructs. Because this is what transpilation with babel has done.

I has assumed the two paradigms where equivalent and that all promises could be rewritten with async/await. Is this true? Or is it an assumption I need to drop.

For a concrete example I have the following code, which contains a promise. I have not seen a way to translate this code to async/await only.

For context, this Mailbox code is for a demo I have to explain the Actor model in the context of the browser/JavaScript

function Mailbox () {
  const messages = []
  var awaiting = undefined

  this.receive = () => {
    if (awaiting) { throw 'Mailbox alread has a receiver'}
    return new Promise((resolve) => {
      if (next = messages.shift()) {
        resolve(next)
      } else {
        awaiting = resolve
      }
    })
  }

  this.deliver = async (message) => {
    messages.push(message)
    if (awaiting) {
      awaiting(messages.shift())
      awaiting = undefined
    }
  }
}
Peter Saxton
  • 4,466
  • 5
  • 33
  • 51
  • It might be more accurate to say that `await` can replace `.then`s - you can't meaningfully *construct* a `Promise` with only `async`/`await` – CertainPerformance Nov 03 '18 at 09:07
  • [`then` with two callbacks is hard to replace with `await`](https://stackoverflow.com/a/44664037/1048572). – Bergi Nov 03 '18 at 09:53
  • Why is `deliver` an `async` function? There's no reason for it to return a promise. On the other hand, `receive` should be marked as `async` to always return a promise (or you should change the `throw …` into a `return Promise.reject(…)`). – Bergi Nov 03 '18 at 09:55

1 Answers1

0

async/await use promises. In fact, they don't do anything useful if you don't have a promise to await. They don't replace promises. You would typically use await instead of .then() on a promise.

Let's look at a simple example. Suppose you have two functions that return promises.

 function delay(t) {
     return new Promise(resolve => {
         setTimeout(resolve, t);
     });
 }

 const rp = require('request-promise');

 function getData(uri) {
     let options = {uri, json: true};
     return rp(options);
 }

Now, you want to get data from three different URLs with a 1 second delay between the requests.

Regular Promises

With regular promises (no async/await), you could do something like this using promise chaining:

function getAllData() {
    let result = {};
    return getData(firstURL).then(data => {
        results.d1 = data;
        return delay(1000);
    }).then(() => {
        return getData(secondURL);
    }).then(data => {
        results.d2 = data;
        return delay(1000);
    }).then(() => {
       return getData(thirdURL);
    }).then(data => {
       results.d3 = data;
       return results;
    });
}

getAllData().then(result => {
   console.log(result);
}).catch(err => {
   console.log(err);
});

Using Async/Await

Using await, you can simplify the sequencing of multiple asynchronous operations, but those asynchronous operations STILL use promises. You are just replacing some of the chained .then() operations with await.

async function getAllData() {
   let result = {};
   result.d1 = await getData(firstURL);
   await delay(1000);
   result.d2 = await getData(secondURL);
   await delay(1000);
   result.d3 = await getData(thirdURL);
   await delay(1000);
   return result;
}

getAllData().then(result => {
   console.log(result);
}).catch(err => {
   console.log(err);
});
jfriend00
  • 683,504
  • 96
  • 985
  • 979