Should synchronous code called by Promise .then create a new Promise

I’ve implemented some code, where asynchronous code is followed by some synchronous functions. For example:

function processSomeAsyncData() {
  asyncFuncCall()
    .then(syncFunction)
    .catch(error);
}

If I understand correctly then is also a Promise. Then, should I create a promise in the synchronous code as well?

function syncFunction() {
  const p = new Promise (function (resolve, reject) {
    //Do some sync stuff
    ...
    resolve(data);
  }
  return p;
}

If that isn’t necessary, how do you reject the promise from the synchronous code if an error occurred?

Here is Solutions:

We have many solutions to this problem, But we recommend you to use the first solution because it is tested & true solution that will 100% work for you.

Solution 1

You don’t need to create a new promise explicitly. There is an easier way.

This example is contrived because it will never fail, but the point is that you don’t have to create a promise and you don’t have to return a resolve(val).

function syncFunction() {
  var j = "hi"
  if(j){
    return j;
  }
  return new Error('i am an error');
}

This will work:

asyncFunction()
  .then(syncFunction);

But if you did it the other way around:

syncFunction()
  .then(asyncFunction);

You would have to define your syncFunction as:

function syncFunction() {

  var j = "hi"
  return new Promise((resolve, reject) => {
    if(j){
      return resolve(j);
    }
    return reject('error');
  })  
}

Edit: To prove to all you non believers out there, give this guy a shot locally on your computer. Proves that you have these many options available to you. 🙂

var Promise = require('bluebird');


function b(h) {
    if(h){
        return h;
    }
    return Promise.resolve('hello from b');
}

function a(z) {
    return new Promise((resolve, reject)=> {
        if(z){return resolve(z)};
        return resolve('hello from a');
    })
}

a().then(b).then(x => console.log(x)).catch(e => console.log(e));
b().then(a).then(x => console.log(x)).catch(e => console.log(e));

Solution 2

No. Synchronous functions may be called from synchronous code and should always fail synchronously! They need not conform to asynchronous callers in any way. If an error occurs just throw an error. Try it:

var asyncFuncCall = () => Promise.resolve();

function syncFunction() {
  throw new Error("Fail");
}

asyncFuncCall()
  .then(syncFunction)
  .catch(e => console.log("Caught: " + e.message));

This works because an exception thrown by a function passed to a .then is converted to a rejection of the promise it is supposed to return.

Additionally, any value returned by a function passed to a .then is converted to a promise resolved with that value. The promise code calling the function takes care of this.

This lets you mix synchronous and asynchronous code without problems:

asyncFuncCallOne()
  .then(() => {
    var x = syncFunction();
    return asyncFuncCallTwo(x);
  })
  .catch(e => console.log(e.message));

Solution 3

It’s optional.

If you return a promise from the syncFunction, then your original promise will resolve only after the new promise resolves and any value returned by the new promise will be passed to the next then in the chain.

If you return a non-Promise value, that will be passed to the next then in the chain.

To reject from within syncFunction, just throw an exception.

Note: Use and implement solution 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply