承诺解决不了问题

Promise resolve will not fire

本文关键字:问题 解决 承诺      更新时间:2023-09-26

我想知道为什么这不会注销解决.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!")
});

您只在第一个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();

如果您想避免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!")
});

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

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