mavo icon indicating copy to clipboard operation
mavo copied to clipboard

Support async functions in expressions

Open LeaVerou opened this issue 4 years ago • 7 comments

Reporting on behalf of @tarfahalrashed

Right now if a function returns a promise, all we get printed out is [object Promise] which is pretty much never desirable. We should check if the return value is a Promise and update the expression when the promise is fulfilled. If what I have in mind works, it should be a rather straight forward change in src/domexpression.js.

I think this would be an easy issue to tackle, @DmitrySharabin do you want to give it a shot? If not, I will work on it this weekend, but thought it would be good practice.

LeaVerou avatar Apr 25 '20 02:04 LeaVerou

I would love to give it a shot. Thanks.

DmitrySharabin avatar Apr 25 '20 05:04 DmitrySharabin

Is this issue still open or done ?

ExplorerAadi avatar Oct 04 '20 13:10 ExplorerAadi

@Aadi-27 Not done. A PR was opened but had some issues and was never merged. I may give it a shot later this month, as we need it for a project. Were you interested in working on it, or asking because you need the functionality?

LeaVerou avatar Oct 05 '20 12:10 LeaVerou

In discussion about this today, I realized that what actually needs to be supported is not just async expressions, but also async data. So it looks like this change should be made in Mavo.Primitive.setValue().

LeaVerou avatar Jan 29 '21 16:01 LeaVerou

Testcaase (currently failing): https://codepen.io/leaverou/pen/dyOoVOK

LeaVerou avatar Feb 02 '21 10:02 LeaVerou

I'm implementing this today and ran into some interesting dilemmas wrt to setting a property/expression to one promise, and then to another promise (let's call them promiseA and promiseB) before promiseA resolves. Let's use timed promises as an example to illustrate.

  • If promiseA resolves after 5 seconds and promiseB after 1 second it seems reasonable that promiseB's resolved value gets applied after 1 second and promiseA's resolved value is never applied.
  • If promiseA resolves after 1 second and promiseB after 5 seconds, do we display the value of promiseA for the 4 seconds in between or do we treat it basically the same way as if only promiseB was specified?

In my current implementation, any old promise is completely discarded once the value is set to another promise, but I think both are reasonable behaviors.

LeaVerou avatar Feb 02 '21 14:02 LeaVerou

Also note that the current implementation only deals with promises as the final output. It does not deal with things like promise + 1, that will still be NaN. Not sure if the use cases are worth the complexity of making every single operation potentially async.

LeaVerou avatar Feb 02 '21 15:02 LeaVerou