0

I have a component which takes some inputs from a user and then does some calculations (which takes some seconds). I want to use async/await block to handle this in UI. Here is the main part of the code:

async function computePV(data) {
   return await pv(data);
}

function compute(e) {
   console.log("button clicked")
   pcvpromise = computePV(data);
   console.log("promise created")
}

$: console.log(pcvpromise)

Here function pv() is the one that does the calculations. Method compute() is called by on:click event from button. My expectations:

  1. Show message "button clicked"
  2. Show message "promise created"
  3. Show the created promise
  4. Wait until the calculations are done and resolve the promise

Reality:

  1. Show message "button clicked"
  2. Wait until the calculations are done
  3. Show message "promise created"
  4. Show the created promise

The code is a copy of code from Svelte tutorial about async/await I just changed a couple of minor things. What am I doing wrong?

  • Can you show your await block? This seems to work as expected in repl – Gavin Jan 14 '23 at 21:03
  • 1
    Code seems incomplete/off, should `computePVSet` be `computePV`? – H.B. Jan 14 '23 at 22:21
  • @Gavin the `pv()` function does some matrix decomposition and returns the result. Nothing special there. @H.B. You are right, I made a typo in question text, fixed now, thanks. @trincot this is Svelte component, `$: ` in front of `console.log()` makes it reactive, it will execute every time the `pcvpromise` is changed. – Sergey Kucheryavskiy Jan 15 '23 at 12:00
  • 1
    @SergeyKucheryavskiy Works as expected, see [REPL1](https://svelte.dev/repl/a93cd4bab6b0471495035e85b31ba7e3?version=3.55.1) (use devtools console to see full log). Note that you shouldn't expect the logged promise to log again when resolved (the promise object being resolved doesn't mean it is reassigned), but the content of the promise object *will* update. Also, your `computePV()` intermediate function is unnecessary, as the `pv()` function already returns a promise, so why not call `pv()` directly? See [REPL2](https://svelte.dev/repl/c0444844e409471da1dd417a1603e50b?version=3.55.1). – Thomas Hennes Jan 15 '23 at 13:22
  • @trincot You were a little too quick to pull the trigger. This is about handling promises in Svelte, not in javascript in general. Your comment about `console.log(pcvpromise)` is misinformed. – Thomas Hennes Jan 15 '23 at 13:27
  • Reopened the question. – trincot Jan 15 '23 at 13:30
  • @ThomasHennes thanks you for the comment. But `pv()` function does not return a promise it just does some calculations for the data and returns the results. However even if I modify this function to return the promise it does not work as expected. But I noticed you use `setTimeout()` in your code. Funny enough if I wrap call of `pv()` with `setTimeout()` it works as expected. Even if the timeout is zero. It does not clarify the problem, but at least it gives a temporary solution. – Sergey Kucheryavskiy Jan 16 '23 at 17:54
  • @SergeyKucheryavskiy Your previous comment doesn't make sense. Why would you `await pv()` if `pv()` does not return a promise? Also, I only used `setTimeout()` to emulate the delay of a promise being resolved (i.e. remote fetch latency or expensive computation). You don't want to be using it in *actual* code. – Thomas Hennes Jan 16 '23 at 18:19
  • I know why you did this. The problem is that I can not simulate delay in REPL without using setTimeout() — REPL treat this as infinite loop. The problem is if I make a promise like this: `return new Promise((resolve, reject) => { resolve(pv(data)) });` it gives problem I described in my initial message. But if I do it like this: `return new Promise((resolve, reject) => { setTimeout(() => { resolve(pv(data)) }, 1) });` it works. Using `setTimeout()` inside promise changes something. – Sergey Kucheryavskiy Jan 16 '23 at 19:21

0 Answers0