2

Why does my code sometimes prints "C" before "A"?

function printstring(string) {
  return new Promise((resolve, reject) => {
    setTimeout(function() {
      document.write(string);
      resolve();
    }, Math.floor(Math.random() * 100) + 1);
  })
}

function printall() {
  printstring("A")
    .then(printstring("C"))
}

printall();

1
  • This is a typo, use a linter with proper rules or a promise library that gives you warnings for this like bluebird. Commented Jun 10, 2018 at 15:35

3 Answers 3

4

then expects a callback. This callback is called, and is passed the resolved value of the promise as the parameter.

In your code, you've provided printstring('C') as callback. So the result of printstring('C'), which is again a promise will be executed with the response. Since you've used a random timeout for execution, the order of printing on the document will depend on it. If the timeout of printing C expires before the timeout of printing A, C will definitely be printed first.

To correct this, use an anonymous function as a then callback, i.e. convert this:

.then(printstring("C"))

to this:

.then(() => printstring("C"))

See the following working demo:

function printstring(string) {
  return new Promise((resolve, reject) => {
    setTimeout(function() {
      document.write(string);
      resolve();
    }, Math.floor(Math.random() * 100) + 1);
  })
}

function printall() {
  printstring("A")
    .then(() => printstring("C"))
}

printall();

Sign up to request clarification or add additional context in comments.

2 Comments

But the callback i.e. resolve should not be called until i have printed A. @31pjy
@FauadHaleem -- The point is that printstring("C") is called first and its result is passed as a callback. It will not care whether the promise is resolved or not.
4
 printstring("A")
   .then(printstring("C"))

Is equal to:

const promise1 = printstring("A");
const promise2 = printstring("C");

 promise1.then(promise2)

So basically you start both actions at the same time, not one after the other. Passing a promise as a callback doesnt really make sense. Instead you may want to wait for the first promise to resolve before starting the next action:

printstring("A").then(function() {
  printstring("C");
});

Comments

0

This has nothing to do with promises, I believe.

Whenever you write a code like this -

function mainFn(callback) {
    // do async stuff
    // call callback when done
    callback();
}

// callback handler
function callbackFn() {
    console.log('callback fn');
}

You need to make sure that you pass callback function's reference to the callback parameter of mainFn(), like so -

// Passess reference to callback function inside mainFn
mainFn(callbackFn);

However, doing something like -

// Executes the callback function and passes it's result into mainFn
mainFn(callbackFn()); 

is totally wrong. This is similar to what you're doing with .then(printstring("C")). It will execute printstring("C") first.

So, to deal with this, wrap it in an anonymous function like so -

 function printall() {
  printstring("A")
    .then(function() { printstring("C"); })
 }

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.