2

Why this code does not work

I want to learn the synchronization in the easy way

const post = [];

function getPost(post) {
     console.log(post)
 }

async function createPost (post) {
  await setTimeout(() => {
    post.push({
      name: "John", work: "Developer"
    })
  }, 1000)
  getPost(post);
}

createPost(post);
Jaber Alshami
  • 336
  • 3
  • 14

1 Answers1

10

It doesn't work because setTimeout doesn't return a promise. If you await a non-Promise, you just get the value (almost¹) immediately. You'd also want to consume the promise returned by createPost, which your code isn't currently doing.

You'd have to make a wrapper for setTimeout that returns a promise, for instance as shown in my answer here, although these days I'd modify it a bit:

function timeout(delay, ...args) {
    return new Promise(function(resolve) {
        setTimeout(resolve, delay, ...args);
    });
}

Here's that applied to your code, although I assume the setTimeout in your code is really a stand-in for some other async operation (ajax, MongoDB, etc.), and I wouldn't structure the code this way (I'd have post created and returned by createPost rather than being an array that createPost closes over):

function timeout(delay, ...args) {
    return new Promise(function(resolve) {
        setTimeout(resolve, delay, args);
    });
}

const post = [];

function getPost(post) {
    console.log(post)
}

async function createPost(post) {
  await timeout(1000);
  post.push({
      name: "John", work: "Developer"
  });
  getPost(post);
}

// Going async at top level
(async () => {
    await createPost(post);
})().catch(error => {
    console.error(error);
});

¹ "almost immediately" a = await b; ... is syntactic sugar (really, really good sugar) for Promise.resolve(b).then(a => ...) (plus error handling). If b isn't a promise, the assignment to a happens in the microtask processing following the task the await occurs in. More about tasks and microtasks in my answer here.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875