Skip to content

Instantly share code, notes, and snippets.

@thanpolas
Created Jun 11, 2013
Embed
What would you like to do?
Promises doodle
function retProm() {
var def = when.defer();
return def.resolve();
}
console.log('one');
retProm().then(function(){console.log('two'));
console.log('three');
// this will print:
//
// one
// three
// two
@domenic
Copy link

domenic commented Jun 11, 2013

This is true. But consider the following example:

var fs = require("fs");

var tickResolvedOn = null;

function readFile(name) {
  var def = when.defer();

  fs.readFile(name, function (err, data) {
    process.nextTick(function () {
      console.log("(X) an extra tick has passed after resolving");
    });

    if (err) {
      return def.reject(err);
    }

    def.resolve(data);
  });
}

readFile("file.txt").then(function onFulfilled(data) {
    console.log("(Y) data received");
});

console.log("(Z) `then` has returned")

By the spec, all that is required is that (Z) come before (Y). There is no requirement that (X) happen before (Y). That is, there is no requirement that an extra tick occur between resolving the promise and calling onFulfilled. Again, all that is required is that then returns before onFulfilled is called, i.e. (Z) happens before (Y).

So what you're claiming is just false. The spec does not "require async resolution" or "add one more async op after original async op finishes."

@thanpolas
Copy link
Author

thanpolas commented Jun 11, 2013

yes you are absolutely right.

That's silly and it is not what i am doing.

The (X) that you mention in this gist, represents the fs.readFile operation in my tests.

fs.readFile is an async op. That async op is what i am trying to emulate by adding one more nextTick.

@thanpolas
Copy link
Author

thanpolas commented Jun 11, 2013

Using your example excluding the nextTick:

var fs = require("fs");

var tickResolvedOn = null;

function readFile(name) {
  var def = when.defer();

  fs.readFile(name, function (err, data) {
    def.resolve(data);
    console.log("(X) an extra tick has passed after resolving");
  });
}

readFile("file.txt").then(function onFulfilled(data) {
    console.log("(Y) data received");
});

console.log("(Z) `then` has returned")

This will print: Z, X, Y

If there was no extraTick in the promise implementation for resolving the promise, it would be: Z, Y, X

@domenic
Copy link

domenic commented Jun 11, 2013

No, this could print Z, Y, X. There is no requirement that X come before Y. The spec is still following as long as Y comes after Z.

@domenic
Copy link

domenic commented Jun 11, 2013

Let me explain further the difference between our two examples. In yours, when you call def.resolve, then has not yet returned. So the implementation must insert an extra tick before calling onFulfilled, to ensure that then returns first.

In my example, when I call def.resolve, then has already returned, since an async operation has already happened. So the implementation does not have to insert an extra tick before calling onFulfilled, since then has already returned.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment