Skip to content

Instantly share code, notes, and snippets.

@vincicat
Created February 9, 2023 16:16
Show Gist options
  • Save vincicat/d03a76718ac464d16004b6e742e05cb9 to your computer and use it in GitHub Desktop.
Save vincicat/d03a76718ac464d16004b6e742e05cb9 to your computer and use it in GitHub Desktop.
smalltalk on JS promises.

Small detail everywhere.

Issues

  1. yes you can resolve with an object with property function then() (also known as thenable), but some engine will not allow you chain the then() call if you resolve your promise in that way.

solution:

a. use Promise.all() to queue your callbacks;

b. put everything in then():

const thenable = {
  then: () => { 
    // your stuff
  }
};
return new Promise((resolve) => {
  return resolve();
}).then(() => {
  return thenable.then();
});
  1. then() callback isn't execute at the point right after resolve() was called (even an immediate resolve())

example

Promise.resolve().then(() => console.log(2));
console.log(1);
// Logs: 1, 2

explainer:

To avoid surprises, functions passed to then() will never be called synchronously, even with an already-resolved promise MDN

Instead of running immediately, the passed-in function (callbacks passed in then()) is put on a microtask queue, will never be invoked before the completion of the current run of the JavaScript event loop.

  1. Promise vs setTimeout

when this occur, Promise > setTimeout

as Promise callbacks are handled as a microtask whereas setTimeout() callbacks are handled as task queues.

Promise Seq: Promise content <(resolve,reject)=>{}> > other tasks in same run > then() > setTimeout

  1. promise and await

async/await can be considered as ECMAScript generators.

(async () => {
  // asyncFunction is an asynchronous function that returns a promise
  const result = await asyncFunction();
  console.log('result:', result);
})();

is same as

asyncController(function* gen() {

  var result = yield asyncFunction();

  return result;
});

function asyncController(genFunction) {
  var genResult = genFunction();

  iterator();
  function iterator(arg) {
    var yieldResult = genResult.next(arg);
    var promiseObject = yieldResult.value;
    promiseObject.then(function (data) {
      // genResult.next(data);
      iterator(data);
    });

  }

}

source

note: except await a function returning a Promise, you can also try to await a Tenable [1] :

const obj = {
  then(callback) {
    console.log('inside then method');
    console.log(callback.toString());
    callback('then method is done');
  }
};

(async() => {
  console.log('start');
  const result = await obj;
  console.log(result);
  console.log('end');
})();

ref

[1] The benefit of the Thenable object in JavaScript

[2] MDN

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