0

Is anyone so kind to advise how can I make .finally message: "End of promise" appear at the end of the code instead of at the beginning?

const posts = [
  { title: "Post One", body: "This is post one" },
  { title: "Post Two", body: "This is post two" },
];

function getPosts() {
  setTimeout(() => {
    posts.forEach((post) => {
      console.log(post.title, post.body);
    });
  }, 1000);
}

function createPostPromise(post) {
  return new Promise((resolve, reject) => {
    const error = false;
    if (!error) {
      setTimeout(() => {
        posts.push(post);
        resolve(true);
      });
    } else {
      reject("Error: Something went wrong");
    }
  }, 2000);
}

createPostPromise({ title: "Post Three", body: "This is post three" })
  .then(getPosts)
  .catch((err) => console.log(err))
  .finally(() => {
    console.log("End of promise");
  });
  • `getPosts` does not return a promise so your code is pretty much the same as `getPosts(); console.log("End of promise");` since there is nothing to define how to wait for `getPosts` to finish. It just starts a timer and completes instantly. [You can turn it into a promise producing function](https://stackoverflow.com/questions/22707475/how-to-make-a-promise-from-settimeout), if you wish. – VLAZ Dec 01 '20 at 20:15
  • Your `getPosts` is ran via `.then()`. This happens after all the promises are resolved. `getPosts` has a `setTimeout` so that's scheduled to run in the future. So, with `.then()` "done", it moves on to `.finally()`. Eventually, in the future the `setTimeout` from `getPosts` is ran. – gen_Eric Dec 01 '20 at 20:16
  • 1
    `setTimeout` is asynchronous – The Bomb Squad Dec 01 '20 at 20:16
  • Thanks - I have converted getPosts so that it returned a Promise and now it works :) – Agnes Liszka Dec 01 '20 at 20:19
  • 1
    @RocketHazmat correction, `getPosts` is run after *the first* promise is resolved. It just queues a timer that fires in the future. But the function does run *before* all the promises settle and *before* the `.finally` callback executes. – VLAZ Dec 01 '20 at 20:19

1 Answers1

1

The code does exactly what you tell it to do: getPosts sets a callback to log the posts in one second, then returns immediately. You probably meant getPosts to be an async function (= a function that returns a promise) that resolves after logging the posts:

const posts = [{
    title: "Post One",
    body: "This is post one"
  },
  {
    title: "Post Two",
    body: "This is post two"
  },
];

function getPosts() {
  return new Promise((resolve) => {
    setTimeout(() => {
      posts.forEach((post) => {
        console.log(post.title, post.body);
      });
      resolve();
    }, 1000);
  })
}

function createPostPromise(post) {
  return new Promise((resolve, reject) => {
    const error = false;
    if (!error) {
      setTimeout(() => {
        posts.push(post);
        resolve(true);
      });
    } else {
      reject("Error: Something went wrong");
    }
  }, 2000);
}

createPostPromise({
    title: "Post Three",
    body: "This is post three"
  })
  .then(getPosts)
  .catch((err) => console.log(err))
  .finally(() => {
    console.log("End of promise");
  });
Nino Filiu
  • 16,660
  • 11
  • 54
  • 84
  • Thats exactly what I have done after reading the first few comments. Thanks a lot for confirming that my solution is correct. – Agnes Liszka Dec 01 '20 at 20:37