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

时间:2017-12-05 03:33:56

标签: javascript node.js promise

此问题之前已被提出过,但我对catch中的拒绝和处理等解决方案感到满意。我想知道我们是否可以在线性承诺链中得到多个幸福流,而不会拒绝(除非出现错误)。

这是我的代码示例:

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)开始,代码将以else条件流动,这就是我想打破链条的时候。

只想知道是否可以在不创建分支或使用承诺拒绝的情况下完成。

2 个答案:

答案 0 :(得分:2)

除了使用promise promise之外,清理代码的一种可能方法是将快乐路径组织到自己的链中,然后将它们组合成一个链。

换句话说,应该按顺序排列的每个步骤序列应该组织在一起。

在你提供的特定代码段中,你总是在你离开后立即行动,所以如果采取的步骤数是偶数,那么就让它成为一个明确的链:

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

答案 1 :(得分:0)

如果您不希望在所采取的总步数为奇数的任何时候继续,那么如果总步数不是奇数,您可以将所有函数包装在一个支票中:

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