Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

returning a promise from the then of another promise

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

like image 472
Charles Bisbee Avatar asked Feb 14 '18 19:02

Charles Bisbee


2 Answers

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();
}
like image 85
Quentin Roy Avatar answered Sep 20 '22 09:09

Quentin Roy


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");
  }));
}
like image 23
Max Shenfield Avatar answered Sep 23 '22 09:09

Max Shenfield