打破承诺链(多个快乐stream和单链)

这个问题之前已经被问过了,但是我并不满意于拒绝和处理破坏快乐stream程的解决scheme。 我想知道我们是否可以在线性的承诺链中获得多个快乐stream而不拒绝(除了错误)。

这是我的代码示例:

const goStraight = (steps) => { return new Promise ((resolve, reject) => { resolve(steps+2); }); }; const turnLeft = (steps) => { return new Promise ((resolve, reject) => { resolve(++steps); }); }; const turnRight = (steps) => { return new Promise ((resolve, reject) => { resolve(++steps); }); }; goStraight(0) .then((total_steps_taken) => { if (total_steps_taken % 2 === 0) return turnLeft(total_steps_taken); else return null; // This is where I want to break the chain }) .then((total_steps_taken) => { return turnRight(total_steps_taken); }).then((total_steps_taken) => { console.log("Finished with Total Steps : "+total_steps_taken); }) 

所以如果我用goStraight(1)开始,它将会处于其他情况,这是我想打破这个链条的时候。 只是想知道是否可以不创build分支或调用拒绝。

除了使用承诺拒绝之外,清理代码的一种可能的方法可能是将快乐的path组织成自己的链条,这些链条组合成一条链。

换句话说,每一个应该发生的顺序,顺序,应该组织在一起。

在你提供的特定代码片段中,在你离开之后,你总是马上行动,所以如果所采取的步骤是偶数的话,

 const happyPath = total_steps_taken => turnLeft(total_steps_taken) .then(turnRight) .then(logSteps); goStraight(0).then(total_steps_taken => { if (total_steps_taken % 2 === 0) { return happyPath(total_steps_taken); } }); 

完整的例子:

 const stepPromise = direction => x => { console.log(`going ${x} steps ${direction}`); return new Promise(resolve => { setTimeout(() => resolve(x), 500); }); } const turnLeft = stepPromise('left') const turnRight = stepPromise('right'); const goStraight = stepPromise('straight'); const logSteps = steps => console.log(`steps taken: ${steps}`); const happyPath = steps => turnLeft(steps) .then(turnRight) .then(steps => console.log(`Took ${steps} steps`)); const branchOrQuit = steps => { if (steps % 2 === 0) { console.log('going down the happy path'); return happyPath(steps); } console.log('quitting'); } const happyExample = () => { console.log('\n --- EVEN ---'); return goStraight(2).then(branchOrQuit); } const sadExample = () => { console.log('\n --- ODD ---'); return goStraight(1).then(branchOrQuit); } happyExample().then(sadExample); 

如果你不想在任何时候继续采取总步骤是奇数,那么你可以包装所有的function在检查,如果总步数不是一个奇数:

 const checkNotOdd = fn => total_steps_taken => (total_steps_taken%2===0) ? Promise.reject("no odd number of steps") : fn(total_steps_taken) checkNotOdd(goStraight)(0) .then( //not checking here, would otherwise reject turnLeft // checkNotOdd(turnLeft) ) .then((total_steps_taken) => checkNotOdd(turnRight) ).then( total_steps_taken => console.log("Finished with Total Steps : "+total_steps_taken), err => console.warn("Failed with:",err) )