[英]JQuery.when() and then() not working with asynchronous event
我正在嘗試從文本文件中讀取行,從文件中選擇一行並將其插入html頁面上的div。
var chosenWord="original word";
function wordFromFile(fileName) {
$.get(fileName, function(data) {
var lines = data.split("\n");
var lineCount = lines.length;
var randomIndex = Math.floor(Math.random() * ((lineCount-1) + 1));
var word = lines[randomIndex];
window.chosenWord = word;
console.log("wordFromFile: "+chosenWord);
});
}
function setRandomWord() {
$.when(wordFromFile("http://mypage.com/words.txt")).then(appendWord());
}
function appendWord() {
console.log("appendWord: "+window.chosenWord);
$('.word').text(window.chosenWord);
}
$(function() {
if($('body').is('.playpage')) {
setRandomWord();
}
});
console shows:
appendWord: original word
wordFromFile: particle //when i refresh the page this word changes but appendWord is always "original word"
我怎樣才能使wordFromFile(fileName)函數首先完成,並且appendWord為全局變量selectedWord獲取相同的值? 我不明白為什么when()和then()函數在我的代碼中不起作用。
您必須在wordFromFile()
返回promise。
function wordFromFile(fileName) {
return $.get(fileName).then(function(data) {
var lines = data.split("\n");
var lineCount = lines.length;
var randomIndex = Math.floor(Math.random() * lineCount);
var word = lines[randomIndex];
window.chosenWord = word;
console.log("wordFromFile: "+chosenWord);
return chosenWord;
});
}
而且,如果您希望最終的chosenWord
值是promise的已解析值,則應從.then()
處理程序中返回它。 另外,請注意,我將$.get()
上的回調更改為.then()
處理程序,以使事情更加一致。 通常,一旦使用了promise,就希望在一個操作中一致地使用它們,而不是在promise中混合使用老式的回調。 這樣做會破壞承諾提供的某些自動錯誤傳播和錯誤處理功能。
然后,您完全不需要在setRandomWord()
使用$.when()
setRandomWord()
因為wordFromFile()
已經返回了一個wordFromFile()
並且您需要在appendWord之后將函數引用傳遞給.then .then()
而不使用括號:
function setRandomWord() {
wordFromFile("http://mypage.com/words.txt").then(appendWord);
}
回顧一下:
wordFromFile()
返回承諾 wordFromFile()
中使用wordFromFile()
.then()
處理函數,而不要使用jQuery回調。 wordFromFile()
$.when()
周圍的$.when()
wordFromFile()
因為它不是必需的。 appendWord
.then()
時,請在appendWord
之后刪除括號。 您所擁有的方式是立即調用appendWord,而不是在promise解決之后的某個時間允許.then .then()
處理程序調用它。 請記住,諾言沒有魔力。 當它們內部的異步操作以某種方式完成時,它們不“知道”。 他們僅在異步操作手動解決承諾時知道異步操作何時完成。 因此,您不能只是在$.when()
放入一些異步操作,並期望$.when()
神奇地知道何時完成異步操作(很多人都嘗試過這一點,顯然這是人們初次嘗試的事情似乎可以預期)。 相反,您將承諾傳遞給$.when()
,異步操作必須解析這些承諾。 在您的情況下,您只有一個承諾,因此不需要$.when()
。 通常只有在您有多個希望等待的諾言時才需要使用它。 當您只有一個承諾時,就可以在其上調用.then()
。
其他注意事項:
chosenWord
傳遞回結果。 這不是必需的,通常被認為是反模式。 這段代碼:
$(function() {
if($('body').is('.playpage')) {
setRandomWord();
}
});
可以簡化為:
$(function() {
$("body.playpage").each(setRandomWord);
});
如果body標簽上具有playpage
類,則它將調用setRandomWord()
。 如果沒有,它將不會調用它。
您可以像這樣從代碼中刪除chosenWord
全局chosenWord
:
function wordFromFile(fileName) {
return $.get(fileName).then(function(data) {
var lines = data.split("\n");
var randomIndex = Math.floor(Math.random() * lines.length);
var word = lines[randomIndex];
console.log("wordFromFile: "+word);
return word;
});
}
function setRandomWord() {
return wordFromFile("http://mypage.com/words.txt")).then(appendWord);
}
function appendWord(word) {
console.log("appendWord: "+word);
$('.word').text(word);
}
$(function() {
$("body.playpage").each(setRandomWord);
});
在這里,選定的單詞成為wordFromFile()
返回的promise的解析值,因此它將被傳遞給該promise之外的任何.then()
處理函數。 當您將appendWord
作為appendWord
.then()
處理函數傳遞時,這意味着該單詞將為您傳遞給appendWord
。 而且,wala不使用全局變量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.