Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to block for a javascript promise and return the resolved result? [duplicate]

I am obviously misunderstanding something about either the way js promises are resolved or about the semantics of "return."

I am being called by a function that expects me to be synchronous - to return a value. Calculating that value requires some asynchronous code (specifically, the ForEach method on a dstore Collection

What I'm trying to accomplish is approximately this, but this does not work in that the function mySynchronousFunction has no return value.

function mySynchronousFunction() {    var accumulator = {};    var myPromise = doAsynchronousThingThatSideEffectsAccumulator();    // Now my caller is expecting the value of accumulator.    myPromise.then(function() {return accumulator;}) } 

I understand that JS has to allow for single-threaded implementations, so that it's not cool to block, but there must be some pattern for gluing asynchronous to synchronous code, that I've just missed.

like image 796
Chris Owens Avatar asked Apr 03 '15 22:04

Chris Owens


People also ask

How do I return after promise is resolved?

resolve() method in JS returns a Promise object that is resolved with a given value. Any of the three things can happened: If the value is a promise then promise is returned. If the value has a “then” attached to the promise, then the returned promise will follow that “then” to till the final state.

Can a promise be resolved twice?

No. It is not safe to resolve/reject promise multiple times. It is basically a bug, that is hard to catch, becasue it can be not always reproducible.

How do I resolve promises before returning?

You can use the async/await syntax or call the . then() method on a promise to wait for it to resolve. Inside of functions marked with the async keyword, you can use await to wait for the promises to resolve before continuing to the next line of the function.

How do you reject promise and resolve?

A Promise executor should call only one resolve or one reject . Once one state is changed (pending => fulfilled or pending => rejected), that's all. Any further calls to resolve or reject will be ignored.


2 Answers

You cannot make a synchronous result out of an asynchronous operation in Javascript. You just cannot do it. If any part of your operation is async, the entire result must be async and you must either use a callback, a promise or some other such mechanism to communicate when the operation is done and the result is ready.

If your async operation already returns a promise (which it looks like), then you should just return that from the wrapper function:

function myWrapperFunction() {    var accumulator = {};    var myPromise = doAsynchronousThingThatSideEffectsAccumulator(accumulator);    // Now my caller is expecting the value of accumulator.    return myPromise.then(function(result) {        // operate on the accumulator object using the async result        return accumulator;    }) }  myWrapperFunction.then(function(accumulator) {    // write your code here that uses the accumulator result }); 

You may also want to note that a function that operates via side effects is rarely the best design pattern. You may as well pass in the input and have it return the output via the resolved promise and avoid side effects entirely.

like image 191
jfriend00 Avatar answered Sep 28 '22 03:09

jfriend00


No, there is no way to make asynchronous code syncronous. Once you have made an asynchronous call, you have to handle the result asynchronously all the way.

JavaScript is single threaded, so if you make a blocking loop that waits for the result, then the code that takes care of the result won't have a chance to run.

If you want to return something from an asynchronous function, you have to return a promise that the calling code can use to handle the result asynchronously.

like image 39
Guffa Avatar answered Sep 28 '22 04:09

Guffa