在一般情況下,建議,因爲你想要一個承諾的創造者是負責解決或拒絕它移動從舊延遲模式了 - 這只是作爲控制流的一噸更容易執行。您不想將解決或拒絕其他代碼的責任傳遞給其他代碼。
如果決定解決或拒絕外部代碼(例如您的rollDice()
函數),則它可以返回用於解析或拒絕的信息。例如,在你的代碼示例中,它可以像這樣完成。
請注意,rollDice()
功能現在只是一個骰子滾動功能,告訴你是否滾動了一個特定的數字。然後由其他函數使用它來確定控制流程,而不是將控制流程放入骰子滾動函數本身。變化的
var rollDice = function() {
console.log("rolling");
return Math.floor(Math.random() * 10) + 1;
}
var rollTillNum = function(num, ms) {
return new Promise(function(resolve) {
var interval = setInterval(function(){
if (rollDice() === num) {
resolve();
clearInterval(interval);
}
}, ms);
});
}
rollTillNum(7, 100).then(function(){
console.log("rolled a 7");
});
總結:
- 無極管理是自包含的,不委派給某一其它功能(使代碼的邏輯更容易遵循),這是主要的原因,以一個使用新的Promise構造函數,而不是延遲構造。
interval
變量現在包含在本地範圍內。
rollDice()
函數現在是通用的,所以它可以在其他上下文中使用。
rollDice()
現在返回一個基於1的值,而不是基於0的值(因爲這就是骰子的工作原理)。
- 而不是硬線
rollTill7()
,它現在是rollTillNum()
,你通過它你想要它達到的數字。
雖然上述方案是更普遍的(利用外部函數提供有關是否應該解決與否反饋),在這種特殊情況下,如果你甚至不需要的rollDice()
功能是外部可用的,那麼它可以只是完全的rollTillNum()
功能的內部所包含的:
var rollTillNum = function(num, ms) {
return new Promise(function(resolve) {
var interval = setInterval(function(){
if ((Math.floor(Math.random() * 10) + 1) === num) {
resolve();
clearInterval(interval);
}
}, ms);
});
}
rollTillNum(7, 100).then(function(){
console.log("rolled a 7");
});
下面是製作成工作演示上面的代碼:
document.getElementById("roll").addEventListener("click", function() {
var start = Date.now();
rollTillNum(7, 100).then(function(cnt) {
var elapsed = ((Date.now() - start)/1000).toFixed(1);
log("It took " + elapsed + " seconds and " + cnt + " rolls to roll a 7");
});
});
var rollDice = function() {
console.log("rolling");
return Math.floor(Math.random() * 10) + 1;
}
var rollTillNum = function(num, ms) {
return new Promise(function(resolve) {
var cntr = 0;
var interval = setInterval(function(){
++cntr;
if (rollDice() === num) {
resolve(cntr);
clearInterval(interval);
}
}, ms);
});
}
function log(x) {
var div = document.createElement("div");
div.innerHTML = x;
document.body.appendChild(div);
}
<button id="roll">
Roll a 7
</button><br><br>
'rollDice()'函數真的沒有理由必須知道任何有關某個promise的任何信息,因此真的沒有理由將promise的解析委託給promise構造函數之外。 'rollDice()'在生活中的工作就是隨機滾動。 'rollTill7()'中的代碼可以使用'rollDice()'中的返回值,然後'rollTill7()'可以確定是否已經達到了期望的數量以及是否應該解析promise。承諾最容易理解,如果它們是在同一代碼塊中創建和解析的。 – jfriend00
@ jfriend00,你是對的。我只是用'new Promise'來代替'defer'。但是,對於您的建議,這是更好的做法...... – zangw