0

I have a simple asynchronous function that works perfectly. But I need to know what every recursive call returns, so I added then (see the line (*)). Unfortunately, result in such then’s is undefined, and the result of the whole function becomes undefined as well.

async function foo(n) {
    try {
        if (n == 0) {
            return 0;
        }
        return n + await foo(n - 1)
            .then(result => { bar(); }); // (*)
    }
    catch (e) {
        console.log(e);
    }
}

Why does this then break the function? Should I use something else?

Dyzzet
  • 75
  • 4
  • How do you know `result` in `.then(result => { bar(); })` is `undefined`…? – deceze Jan 30 '19 at 12:41
  • `console.log(result);` shows that. – Dyzzet Jan 30 '19 at 12:43
  • 1
    You have `console.log(result)` *inside* that `then` callback, next to `bar()`…? – deceze Jan 30 '19 at 12:46
  • 2
    besides, `bar` is called but nothing is returned since it's wrapped in a block, hence `n + undefined` should return `NaN` instead. – briosheje Jan 30 '19 at 12:48
  • Yes, `console.log(result)` is inside `then`, next to `bar()`. – Dyzzet Jan 30 '19 at 12:50
  • 1
    Fine, so i guess it's joining the `.catch` somehow, hence the `undefined`. Otherwise it would be NaN. May you please add further informations? It's quite hard to give the proper answer right now. – briosheje Jan 30 '19 at 12:51
  • Adding `.catch` after `.then` didn’t help. I don’t know which information I can give. Without `.then` it works fine, adding `.then` breaks everything. – Dyzzet Jan 30 '19 at 13:00
  • By the way, `foo(0)` returns `0`, it’s the only working case. – Dyzzet Jan 30 '19 at 13:05
  • @Dyzzet of course it does, since it joins `if (n == 0)`. Your second return will never work as stated above, since you are returning `undefined` on the `await` statement. Besides, what does `bar` do? Besides, it's joining the `catch` of the try catch, not the promise's catch, that's what I meant above. – briosheje Jan 30 '19 at 13:27
  • 1
    Avoid [`await`ing a `.then(…)` chain](https://stackoverflow.com/a/54387912/1048572)! – Bergi Jan 30 '19 at 13:38

1 Answers1

3

That's just how then works - it creates a new promise for the result of the callback. Your result => { bar(); } callback doesn't return anything, so you get undefined as the result. You would need to write

return n + await foo(n - 1).then(result => { bar(); return result; });
//                                                  ^^^^^^^^^^^^^^

but really you should not mix then callbacks into async/await code. The equivalent of that corrected code would be

const result = await foo(n - 1);
bar();
return n + await result; // (the `await` is unnecessary and should be left out)

whereas your original code does

const result = await foo(n - 1);
bar();
return n + await undefined;
Bergi
  • 630,263
  • 148
  • 957
  • 1,375