Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ES6 Promises - Calling synchronous functions within promise chain

I'm currently experimenting with promises and have a really basic question!

Within a promise chain, would it be bad practice to call a synchronous function? For example:

.then(function(results) {

    if(checkIfResultInMemory(results) === true){
       return getTotalFromMemory()
    }

   return results;

  })

Or should my sync functions be refactored to return promises also?

like image 933
Ben Avatar asked Dec 18 '15 03:12

Ben


2 Answers

Within a promise chain, would it be bad practice to call a synchronous function?

No, it is not a bad practice at all. It is one of many expected and useful practices.

You are perfectly free to call either synchronous functions within the promise chain (from within .then() handlers) or asynchronous functions that then return a new promise.

When you return something from a .then() handler, you can return either a value (which becomes the resolved value of the parent promise) or you can return another promise (which chains onto the previous promise) or you can throw which works like returning a rejected promise (the promise chain becomes rejected).

So, that means you can call a synchronous function and get a value from it or call an async function and get another promise and then return either from the .then() handler.

All of these synchronous things are perfectly legal and each have their own objective. Here are some synchronous happenings in the .then() handler:

// modify resolved value
someAsync().then(function(val) {
    return val + 12;
});

// modify resolved value by calling some synchronous function to process it
someAsync().then(function(val) {
    return someSynchronousFunction(val);
});

// synchronously check the value and throw to change the promise chain
// to rejected
someAsync().then(function(val) {
    if (val < 0) {
        throw new Error("value can't be less than zero");
    }
    return val;
});

// synchronously check the value and return a rejected promise 
// to change the promise chain to rejected
someAsync().then(function(val) {
    if (val < 0) {
        return Promise.reject("value can't be less than zero");
    }
    return val;
});

Here's a little example of an async operation that returns a promise followed by three synchronous .then() handlers and then outputting the final value:

function delay(t, val) {
    return new Promise(function(resolve) {
        setTimeout(function() {
            resolve(val);
        }, t);
    });
}

function increment5(val) {
    return val + 5;
}

delay(500, 10).then(increment5).then(function(val) {
    return val - 3;
}).then(function(final) {
    document.write(final);
});

Note: You only generally only want to use promises when you have or may have asynchronous operations because if everything is synchronous, then pure synchronous code is both faster to execute and easier to write. But, if you already have at least one async operation, you can certainly mix synchronous operations with that async operation and use promises to help structure the code.

like image 125
jfriend00 Avatar answered Oct 08 '22 18:10

jfriend00


A then callback function should:

  • return another promise
  • return a synchronous value (or undefined)
  • throw a synchronous error
like image 41
trquoccuong Avatar answered Oct 08 '22 17:10

trquoccuong