承诺决心不会解雇

时间:2016-10-29 00:45:23

标签: javascript promise ecmascript-6

我想知道为什么这不会退出解析.then方法。想法是注销每个失败,然后一旦值匹配,就注销.then方法中的“Winner Winner”。

var winner = 5;
var ticket = 0;
var roll = function() {
  ticket = Math.round(Math.random() * 10);
}
var play = function() {
  roll();
  return new Promise(function(resolve, reject) {
    if (ticket === winner) {
      resolve();
    } else {
      console.log("Sorry Try Again");
      play();
    }
  });

}


play().then(function() {
  console.log("Winner Winner!")
});

2 个答案:

答案 0 :(得分:1)

当第一个play()成功而不是递归时,您只记录获胜者。在内部通话中添加.then()

var winner = 5;
var ticket = 0;
var roll = function() {
  ticket = Math.round(Math.random() * 10);
}
var play = function() {
  roll();
  return new Promise(function(resolve, reject) {
    if (ticket === winner) {
      resolve();
    } else {
      console.log("Sorry Try Again");
      play().then(function() {
        console.log("Winner Winner");
      });
    }
  });

}


play().then(function() {
  console.log("Winner Winner!")
});

如果您不想在两个地方重复该代码,请定义一个执行此操作的函数。

var winner = 5;
var ticket = 0;
var roll = function() {
  ticket = Math.round(Math.random() * 10);
}
var play = function() {
  roll();
  return new Promise(function(resolve, reject) {
    if (ticket === winner) {
      resolve();
    } else {
      console.log("Sorry Try Again");
      playtest();
    }
  });

}

function playtest() {
  play().then(function() {
    console.log("Winner Winner!")
  });
}

playtest();

答案 1 :(得分:1)

如果你想避免too much recursion - 即使有这么小的随机范围也会发生这种情况,你可以这样做

var retry = function retry(fn) {
  return fn().catch(function () {
    return retry(fn);
  });
};

var winner = 5;
var ticket = 0;
var roll = function roll() {
  ticket = Math.round(Math.random() * 10);
};
var play = function play() {
  roll();
  return new Promise(function (resolve, reject) {
    if (ticket === winner) {
      resolve();
    } else {
      console.log("Sorry Try Again");
      reject();
    }
  });
};

retry(play).then(function () {
  console.log('winner');
});

然而!!!最简单的解决方法是

var winner = 5;
var ticket = 0;
var roll = function() {
  ticket = Math.round(Math.random() * 10);
}
var play = function() {
  roll();
  return new Promise(function(resolve, reject) {
    if (ticket === winner) {
      resolve();
    } else {
      console.log("Sorry Try Again");
      // setTimeout to avoid recursion
      setTimeout(function() {
          resolve(play());
      }, 0);
      // OR use Promise.resolve().then to asynchify the call to play so as to also avoid recusrion
      Promise.resolve().then(function() {
          resolve(play());
      });
    }
  });

}


play().then(function() {
  console.log("Winner Winner!")
});

而不是仅仅再次调用游戏,resolve(play()) - 这样做也可能导致too much recursion

要克服递归问题,只需将resolve(play())包装在setTimeout Promise.resolve().then(function() { ... });中,如代码所示(使用一个或另一个,而不是两个:p)