Cómo estructurar Promesas anidadas

Tengo una situación en la que creo que la única opción para mí es anidar algunas promesas entre ellas. Tengo una Promesa que debe realizarse y un método que hace algo hasta que la Promesa esté completa. Algo como esto:

let promise = new Promise((resolve, reject) => { // Do some stuff }); doSomethingUntilPromiseisDone(promise); 

Sin embargo, dentro de mi promesa, necesito ejecutar otro método que devuelva otra promesa:

 let promise = new Promise((resolve, reject) => { fetchValue(url) .then((value) => { // Do something here }).catch((err) => { console.error(err); }); }); doSomethingUntilPromiseisDone(promise); 

Pero ahora, en la statement then del método fetchValue , tengo otro método que necesito para ejecutar eso, adivina qué, devuelve otra promesa:

 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); 

Entonces, al final, tengo una Promesa, dentro de una Promesa, dentro de una Promesa. ¿De alguna forma puedo estructurar esto mejor para que sea más sencillo? Parece que anidarlos uno dentro del otro es contrario al enfoque de encadenamiento previsto de Promesa.

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)) 

puede usar un generator para aplanar sus promesas anidadas ( Bluebird.couroutine o Generadores )

 //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();