javascript - How to structure nested Promises - Stack Overflow

admin2025-04-18  1

I have a situation where I think the only choice for me is to nest some Promises within each other. I have a Promise that needs to be performed and a method that does something until that Promise is plete. Something like this:

let promise = new Promise((resolve, reject) => {

  // Do some stuff

});

doSomethingUntilPromiseisDone(promise);

However, within my Promise, I need to execute another method that returns another Promise:

let promise = new Promise((resolve, reject) => {

  fetchValue(url)
    .then((value) => {

      // Do something here

    }).catch((err) => {
      console.error(err);
    });

});

doSomethingUntilPromiseisDone(promise);

But now, in the fetchValue method's then statement, I have another method I need to execute that, guess what, returns another Promise:

let promise = new Promise((resolve, reject) => {

  fetchValue(url)
    .then((value) => {

      saveToCache(value)
        .then((success) => {

          console.log('success!!');
          resolve('success');

        });

    }).catch((err) => {
      console.error(err);
    });

});

doSomethingUntilPromiseisDone(promise);

So in the end, I have a Promise, within a Promise, within a Promise. Is there someway I can structure this better so that it is more straightforward? It seems like nesting them within each other is counter to Promise's intended chaining approach.

I have a situation where I think the only choice for me is to nest some Promises within each other. I have a Promise that needs to be performed and a method that does something until that Promise is plete. Something like this:

let promise = new Promise((resolve, reject) => {

  // Do some stuff

});

doSomethingUntilPromiseisDone(promise);

However, within my Promise, I need to execute another method that returns another Promise:

let promise = new Promise((resolve, reject) => {

  fetchValue(url)
    .then((value) => {

      // Do something here

    }).catch((err) => {
      console.error(err);
    });

});

doSomethingUntilPromiseisDone(promise);

But now, in the fetchValue method's then statement, I have another method I need to execute that, guess what, returns another Promise:

let promise = new Promise((resolve, reject) => {

  fetchValue(url)
    .then((value) => {

      saveToCache(value)
        .then((success) => {

          console.log('success!!');
          resolve('success');

        });

    }).catch((err) => {
      console.error(err);
    });

});

doSomethingUntilPromiseisDone(promise);

So in the end, I have a Promise, within a Promise, within a Promise. Is there someway I can structure this better so that it is more straightforward? It seems like nesting them within each other is counter to Promise's intended chaining approach.

Share Improve this question edited Oct 25, 2016 at 15:01 Jake Wilson asked Oct 25, 2016 at 5:43 Jake WilsonJake Wilson 91.4k97 gold badges260 silver badges371 bronze badges 6
  • Looks like you are trying to code async calls backs with Promise -- why not just use callbacks instead? – Soren Commented Oct 25, 2016 at 5:45
  • Where do you call resolve()? – guest271314 Commented Oct 25, 2016 at 5:51
  • 1 Where is the got method? – thefourtheye Commented Oct 25, 2016 at 6:05
  • Sorry the got was a typo. I was referring to the fetchValue method. – Jake Wilson Commented Oct 25, 2016 at 14:21
  • @Soren Well, doSomethingUntilPromiseIsDone takes a Promise. fetchValue returns a Promise, and savetoCache returns a Promise. If Promises are what these methods are returning how would I use callbacks at all? – Jake Wilson Commented Oct 25, 2016 at 14:22
 |  Show 1 more ment

3 Answers 3

Reset to default 5

Use .then()

let doStuff = (resolve, reject) => {/* resolve() or reject() */};
let promise = new Promise(doStuff);
doSomethingUntilPromiseisDone(
  promise 
  .then(value => fetchValue(url))
  .then(value => value.blob())
  .then(saveToCache)
)
.then(success => console.log("success!!"))
.catch(err => console.error(err))

you can use generator to flatten your nested promises (Bluebird.couroutine or Generators)

//Bluebird.couroutine
const generator = Promise.coroutine(function*() {
  try {
     const value = yield fetchValue(url);
     const success = yield saveToCache(value);
     console.log('success:', success);
  } catch(e) {
     console.error(err);
  }    
}));

generator();

Each function will call the next one with the result of the method before.

var promises = [1,2,3].map((guid)=>{
    return (param)=> {
      console.log("param", param);
      var id = guid;
      return new Promise(resolve => {
        // resolve in a random amount of time
        setTimeout(function () {
          resolve(id);
        }, (Math.random() * 1.5 | 0) * 1000);
      });
    }
}).reduce(function (acc, curr, index) {
  return acc.then(function (res) {
    return curr(res[index-1]).then(function (result) {
      console.log("result", result);
      res.push(result);
      return res;
    });
  });
}, Promise.resolve([]));
promises.then(console.log);
转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1744965144a277151.html

最新回复(0)