正如已經提到的,在咬你的部分是事件的反應,異步以及可能不是你會如何以及何時期待踢遞歸函數的組合。它更進一步,但這足以說明出現問題的地方,而無需進入JS之間的元編程和瀏覽器引擎之間的元編程。
現在,其他答案已經告訴你爲什麼它不會按照你的想法工作,我建議問題的根源在於你試圖管理應該發生一次的事情(切換按鈕),可能會發生一百次,如果你寫了更多的代碼並將其翻過來,可視化起來會更容易。
或許重構,看起來有點像這樣,可能會使事情變得更簡單:
var button = {
el : $("#responseButton"), // cache your references
setDisabled : function (state) { button.el.prop("disabled", state); },
enable : function() { button.setDisabled(false); },
disable : function() { button.setDisabled(true); },
handleClick : function() {
button.disable();
Utilities.typeEffect(0, function() { button.enable(); });
}
},
dialogBox = {
// if you're going to call this 100x in a row, cache it
el : $("#npc_dialog"),
append : function (text) { dialogBox.el.append(text); }
},
sec = 1000,
textSpeed = {
fast : 1/25 * sec, // 25x /sec
medium : 1/10 * sec, // 10x /sec
slow : 1/ 5 * sec // 5x /sec
};
button.el.on("click", button.handleClick);
Utilities.typeEffect = function (index, done) {
if (index >= game.data.NPCdialog.length) {
game.data.enableCycle = true;
return done();
} else {
var character = game.data.NPCdialog[index];
dialogBox.append(character);
setTimeout(function() {
Utilities.typeEffect(index+1, done);
}, textSpeed.fast);
}
};
你應該注意到,我改變了實際.typeEffect
的非常非常小的內部。
我做了什麼做的是快速構建一個快速的button
抽象,它包含對元素的緩存引用(不要讓jQuery在頁面上查找它,每秒25x),添加一些quick'n'dirty幫助方法......然後我給出了事件處理的按鈕控件,包括知道如何清理的時間。
如果你會發現,我給.typeEffect
一個參數,done
,和我通過它的參數是由button
定義的函數,它知道如何清理自己,當一切都完了。該函數並沒有更大,然而,我現在通過傳遞迴調來執行輸入阻塞/解除阻塞一次。
更好的是,我可以保證它在遞歸開始之前就被阻塞了,並且在最後一次遞歸發生之後它就被解除阻塞,沒有任何不明確的狀態阻礙。
我也緩存了對話框,重新加快了這個過程;
這些天,jQuery確實有奇蹟,但這仍然應該被緩存。
如果我把它進一步,我可能會做typeEffect
一個對話框,書寫組件插件,使幾種不同類型的影響可能在被丟棄。
我可能也開始傳遞遞歸運行它所關心的其他參數(文本速度,參考對話框等),以便它們更易於交換,並且該函數變得更加可重用(並且更容易看到它的工作原理)。
請注意,這不是真的的答案。這是解決方案,它不僅解決問題,而且說明未來如何預防問題。
如果可行,請使用它,如果不行,請勿使用。
如果這個概念有效,但它不是你的風格,然後改變它(儘管如此,避免使用setTimeout
中的字符串......應該在幾年前停止教學;如果你是性能殺手,安全危害在用戶創建的字符串中混搭,容易造成非嚴格的eval-context錯誤......所有的好東西)。
當然你會看到setTimeout,那裏。 – Norguard
...看起來像我選錯了一週,放棄嗅探膠水。也就是說,我相信它會是'.charAt(index)',然後'process(index + 1)',因爲解析後綴的時候。 '.charAt(++ index)'是'.charAt(index + 1)'。 – Norguard
@Norguard - 謝謝,修正。 – Malvolio