1

Here is my situation:

fetchData(foo).then(result => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(result + bar);
        }, 0)
    });
}).then(result => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve( result + woo);
        }, 0)
    });
}).then(result => {
    setTimeout(() => {
        doSomething(result);
    }, 0)
});

Where each setTimeout is a different async operation using the callback pattern.

It is really painfull to wrap each function inside a promise, I feel like the code should look more like this:

fetchData(foo).then(result => {
    setTimeout(() => {
        return result + bar;
    }, 0)
}).then(result => {
    setTimeout(() => {
        return result + woo;
    }, 0)
}).then(result => {
    setTimeout(() => {
        doSomething(result);
    }, 0)
});

Obviously this doesn't work.

Am I using Promises right? Do I really have to wrap all existing async function in promises?

EDIT:

Actually I realize my example was not totally reprensentative of my situation, I did not make it clear that the setTimeout in my example is meant to reprensent en async operation. This situation is more representative of my situation:

fetchData(foo).then(result => {
    return new Promise((resolve, reject) => {
        asyncOperation(result, operationResult => {
            resolve(operationResult);
        }, 0)
    });
}).then(result => {
    return new Promise((resolve, reject) => {
        otherAsyncOperation(result, otherAsyncResult => {
            resolve( otherAsyncResult);
        }, 0)
    });
}).then(result => {
        doSomething(result);
});
5
  • You can use custom event if you don't wanna use promise. This event will be triggered each detect change! ( sitepoint.com/javascript-custom-events ) .... But why you don't like using promise? Commented Mar 16, 2017 at 8:36
  • 1
    There are modules like pify that can help you promisify existing callback-based async functions. Also, a reasonable number of packages offer both promise and callback support for their async functions (when you don't pass a callback function, they return a promise). But I can't say if this'll apply to your situation. Commented Mar 16, 2017 at 8:45
  • ^^ yeah or bluebird is very simple, and behaves just like native Promises but more friendly to node style callbacks. link Commented Mar 16, 2017 at 8:51
  • Why do you apply setTimeout inside every .then? Commented Mar 16, 2017 at 8:58
  • Try .then(result => new Promise(resolve => asyncOperation(result, resolve, 0))) No need to be more verbose than necessary. Don't put anything but the smallest code necessary inside promise constructor executor functions. Commented Mar 17, 2017 at 19:50

2 Answers 2

3

Am I using Promises right? Do I really have to wrap all existing async function in promises?

Yes. Yes.

I feel like the code should look more like this

No, it shouldn't. It rather should look like this:

function promiseOperation(result) {
    return new Promise((resolve, reject) => {
        asyncOperation(result, resolve, 0)
    });
}
function otherPromiseOperation(result) {
    return new Promise((resolve, reject) => {
        otherAsyncOperation(result, resolve, 0)
    });
}

fetchData(foo).then(promiseOperation).then(otherPromiseOperation).then(doSomething);

It is really painfull to wrap each function inside a promise

Well, don't repeatedly write it out every time. You can abstract this wrapping into a function!

function promisify(fn) {
    return value => new Promise(resolve => {
        fn(value, resolve, 0)
    });
}
const promiseOperation = promisify(asyncOperation);
const otherPromiseOperation = promisify(otherAsyncOperation);
fetchData(foo).then(promiseOperation).then(otherPromiseOperation).then(doSomething);

Notice that most promise libraries come with a such a promisification function included, so your whole code reduces to these three lines.

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

Comments

0

You are using promise right. Just a small note on the first snippet of code: you are not returning a promise from the last then() callback:

...
}).then(result => {
    setTimeout(() => {
        doSomething(result);
    }, 0)
});

This is correct if you need simply to do an async operation without returning to the caller of fetchData the value of the last async operation. If you need to return this value, you need to convert to promise this operation too:

fetchData(foo).then(result => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(result + bar);
        }, 0)
    });
}).then(result => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(result + woo);
        }, 0)
    });
}).then(result => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(doSomething(result));
        }, 0)
    });  
});

Here I suppose doSomething is a sync function returning a value.

Said so, if you want to reduce the noise of create the promise to wrap setTimeout every time, you can create a utility function setTimeoutWithPromise:

function setTimeoutWithPromise(operation, millisec) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(operation());
        }, millisec)
    });
}

And clean your code:

fetchData(foo)
    .then(result => setTimeoutWithPromise(() => result + bar, 0))
    .then(result => setTimeoutWithPromise(() => result + woo, 0))
    .then(result => setTimeoutWithPromise(() => doSomething(result), 0));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.