我想知道为什么这不会退出解析.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!")
});
答案 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)