Obviamente, estoy malinterpretando algo sobre la forma en que se resuelven las promesas js o sobre la semántica de "retorno".
Me llama una función que espera que sea sincrónico, para devolver un valor. Calcular ese valor requiere algún código asíncrono (específicamente, el método ForEach en una colección dstore
Lo que estoy tratando de lograr es aproximadamente esto, pero esto no funciona porque la función mySynchronousFunction no tiene valor de retorno.
function mySynchronousFunction() { var accumulator = {}; var myPromise = doAsynchronousThingThatSideEffectsAccumulator(); // Now my caller is expecting the value of accumulator. myPromise.then(function() {return accumulator;}) }
Entiendo que JS tiene que permitir implementaciones de un solo subproceso, por lo que no es bueno bloquear, pero debe haber algún patrón para pegar código asíncrono a síncrono, que acabo de perder.
No puede obtener un resultado síncrono de una operación asíncrona en Javascript. Simplemente no puedes hacerlo. Si alguna parte de su operación es asíncrona, el resultado completo debe ser asíncrono y debe usar una devolución de llamada, una promesa o algún otro mecanismo similar para comunicar cuándo se realiza la operación y el resultado está listo.
Si su operación asíncrona ya devuelve una promesa (que parece), entonces debería devolverla desde la función contenedora:
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 });
También es posible que desee tener en cuenta que una función que opera a través de efectos secundarios rara vez es el mejor patrón de diseño. También puede pasar la entrada y hacer que devuelva la salida a través de la promesa resuelta y evitar los efectos secundarios por completo.
No, no hay forma de hacer que el código asincrónico sea sincrónico. Una vez que haya realizado una llamada asíncrona, debe manejar el resultado de forma asíncrona hasta el final.
JavaScript tiene un solo subproceso, por lo que si realiza un bucle de bloqueo que espera el resultado, el código que se encarga del resultado no tendrá la oportunidad de ejecutarse.
Si desea devolver algo de una función asíncrona, debe devolver una promesa que el código de llamada puede usar para manejar el resultado de forma asíncrona.