returning a promise from the then of another promise
Asked Answered
P

3

8

i am a little new at this. Please help

I am trying to return a promise from a function. This seems to work well until I try to return the promise in the then of an existing promise.

I am trying to do this in a FireFox extension. The code below is written for node.js as I thought it might give more explanation. I cannot figure out how to make it work.

function topLevel calls function level2. level2 waits for a promise to resolve and then returns a promise to level1. level1 logs in its .then.

level2 calls level3 after its internal promise is resolved and returns a new promise

In the example all promises resolve immediately. The example is paired down to the essentials

function topLevel() {
  level2()
  .then(() => {
      console.log("topLevel resolved")
    })
}

let testError=true;

function level2() {
  if(testError) {
    new Promise((resolve, reject) => {
      resolve("Level 2");
    })
      .then(() => {
        return (level3());
      })
  }
  else {
    return (level3());
  }
}


function level3(){
  return (new Promise((resolve, reject) => {
    resolve("Level 3");
  }));


}


topLevel();

there is a variable "testError" which changes the behavior of level 2. When set to "true" level2 waits for a promise and returns a promise from level3 in that promises then statement. level3 is run but the console.log in level1 never executes and an error results. When set to false everything works (promise from level3 is returned directly rather than in .then. The error is Cannot read property 'then' of undefined in toplevel .then.

The firefox webextension code from a background script is below

browser.browserAction.onClicked.addListener(topLevel);


function topLevel() {
  level2()
  .then(() => {
      console.log("topLevel resolved")
    })
}


function level2() {
  new Promise((resolve, reject) => {
    resolve("Level 2");
  })
    .then(() => {
      return (level3());
    })
}


function level3(){

  return (new Promise((resolve, reject) => {
    resolve("Level 3");
  }));


}

It causes a warning in level2 between the .then and return statements that "level2 is undefined". and again the log in level one never happens.

Any way to make this work?? I need to rely on this pattern

Pisistratus answered 14/2, 2018 at 19:55 Comment(0)
P
2

I think it's as simple as adding a return before new Promise... in line 12. Revised code:

function topLevel() {
  level2()
  .then(() => {
    console.log("topLevel resolved")
  })
}

let testError = true;

function level2() {
  if(testError) {
    // Added "return" here
    return new Promise((resolve, reject) => {
      resolve("Level 2");
    })
    .then(() => {
      return (level3());
    })
  }
  else {
    return (level3());
  }
}

function level3() {
  return (new Promise((resolve, reject) => {
    resolve("Level 3");
  }));
}
Photooffset answered 14/2, 2018 at 20:0 Comment(0)
C
4

level2 does not return anything when testError is true.

The thenable (the function given to then) is a function. The return statement inside the thenable only concern the thenable itself (just like any function).

Change to

function level2() {
  if (testError) {
    return new Promise((resolve, reject) => {
      resolve("Level 2");
    }).then(() => {
      return level3();
    });
  }
  return level3();
}
Calcicole answered 14/2, 2018 at 20:0 Comment(1)
This did it. Thanks to all who answered. I had a "work around" using await but tried that approach for something else and it is not working.Pisistratus
P
2

I think it's as simple as adding a return before new Promise... in line 12. Revised code:

function topLevel() {
  level2()
  .then(() => {
    console.log("topLevel resolved")
  })
}

let testError = true;

function level2() {
  if(testError) {
    // Added "return" here
    return new Promise((resolve, reject) => {
      resolve("Level 2");
    })
    .then(() => {
      return (level3());
    })
  }
  else {
    return (level3());
  }
}

function level3() {
  return (new Promise((resolve, reject) => {
    resolve("Level 3");
  }));
}
Photooffset answered 14/2, 2018 at 20:0 Comment(0)
D
0

You need to return the new Promise you create in the level2 function.

Dinothere answered 14/2, 2018 at 20:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.