JS Async/Await vs Promise vs Callbacks

Viewed 5699

I'm trying to understand difference between these 3. Callbacks & Promises are clear but I don't get the usage of async/await. I know it is the syntactic sugar of promises but what I've tried didn't work. I'm sharing the piece of code I've tried to understand all this...

I've tried with an array

var array = [1,2,3];

and 2 functions

  • get() executes in 1 sec & console the array
  • post(item) executes in 2 sec & push a new item in the array

Now, what I want to get is that the post method should execute first & get after it so that the result on the console should be [1,2,3,4] not [1,2,3]

CALLBACK

function get() {
    setTimeout(() => console.log(array), 1000);
}

function post(item, callback) {
    setTimeout(() => {
        array.push(item);
        callback();
    }, 2000);
}

function init() {
    post(4, get);
    // returns [1,2,3,4] ✅
}

It works fine but in case of too many callbacks, code will be messier... So,

PROMISE

function get() {
    setTimeout(() => console.log(array), 1000);
}

function post(item) {
    return new Promise((resolve, reject) => setTimeout(() => {
        array.push(item)
        resolve();
    }, 2000));
}

function init() {
    post(4).then(get);
    // returns [1,2,3,4] ✅
}

Ok with much cleaner code. But still multiple then calls... Now,

Async/Await

function get() {
    setTimeout(() => console.log(array), 1000);
}

function post(item) {
    setTimeout(() => {
        array.push(item)
    }, 2000);
}

async function init() {
    await post(4);
    get();
    // returns [1,2,3] ❌

    await post(4);
    await get();
    // returns [1,2,3] ❌

    post(4);
    await get();
    // returns [1,2,3] ❌
}

Much more cleaner version but neither way, it worked... I've also tried this (convert both functions (post & get) to async and call with then)

async function get() {
    setTimeout(() => console.log(array), 1000);
}

async function post(item) {
    setTimeout(() => {
        array.push(item)
    }, 2000);
}

async function init() {
    post(4).then(get);
    // returns [1,2,3] ❌
}

But still of no use. So I'm totally confused about this feature (i.e. async/await). Please elaborate on this very example. And also please tell me about Promise.resolve & Promise.all in this same context! Thanks

3 Answers

async and await are tools to manage promises

await post(4);

Here you are waiting for the promise returned by post to be resolved.

function post(item) {
    setTimeout(() => {
        array.push(item)
    }, 2000);
}

However, post does not return a promise, so it does nothing useful.

You had a working implementation of post with a promise before. So use that:

function post(item) {
    return new Promise((resolve, reject) => setTimeout(() => {
        array.push(item)
        resolve();
    }, 2000));
}

Your attempts with async and await do not use anything that resolves a promise after a delay. As it stands, all the async functions you have defined, return a promise that immediately resolves.

You'll want to use a utility function that you can often use. It returns a promise that resolves after a given number of milliseconds, using setTimeout:

// utility function
let delay = ms => new Promise(resolve => setTimeout(resolve, ms));

let array = [1, 2, 3];

async function get() {
    await delay(1000);
    console.log(array);
}

async function post(item) {
    await delay(1000);
    array.push(item)
}

async function init() {
    await post(4);
    await get();
}

init();
console.log("wait for it...");

Similar to what you did in PROMISE.

Wrap post setTimeout in a promise and return it.
call resolve inside the body of the settimeout.

function post(item) {
 return new Promise((resolve)=>{
   setTimeout(() => {
     array.push(item)
     resolve()
   }, 2000);
 })
}

then you can use it like that :

async function init() {
    await post(4);
    get();
    }

Related