我正在尝试从文本文件中读取行,从文件中选择一行并将其插入到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的相同值?我不明白为什么当()和then()函数在我的代码中不起作用时。
答案 0 :(得分:0)
您必须在wordFromFile()
中退回承诺。
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()
处理程序,以使事情更加一致。一般来说,一旦你使用了promises,你就想在一个操作中一致地使用它们,而不是在promises中混合使用老式的回调。这样做会破坏承诺提供的一些自动错误传播和错误处理功能。
然后,您根本不需要在$.when()
中使用setRandomWord()
,因为wordFromFile()
已经返回了一个承诺,您需要将函数引用传递给.then()
} appendWord之后没有parens:
function setRandomWord() {
wordFromFile("http://mypage.com/words.txt").then(appendWord);
}
回顾一下:
wordFromFile()
.then()
内使用wordFromFile()
处理程序而不是jQuery回调。$.when()
周围wordFromFile()
,因为它不是必需的。appendWord
时删除.then()
后的parens。您使用它的方式是立即调用appendWord,而不是允许.then()
处理程序稍后在promise解析时调用它。请记住,承诺没有神奇的力量。他们不知道"当它们内部的异步操作以某种方式完成时。只有在异步操作手动解析承诺时,它们才会知道异步操作何时完成。所以,你不能在$.when()
中放置一些异步操作,并期望$.when()
神奇地知道异步操作何时完成(很多人尝试这样做,显然这是人们的新事物)承诺似乎期待)。相反,您将承诺传递给$.when()
,异步操作必须解决这些承诺。在您的情况下,您只有一个承诺,因此不需要$.when()
。通常只有在您想要等待多个承诺时才需要它。如果您只有一个承诺,则可以在其上调用.then()
。
其他注意事项:
chosenWord
来回复结果。这不是必要的,通常被认为是一种反模式。此代码:
$(function() {
if($('body').is('.playpage')) {
setRandomWord();
}
});
可以简化为:
$(function() {
$("body.playpage").each(setRandomWord);
});
如果正文标记上有playpage
类,则会调用setRandomWord()
。如果没有,它就不会打电话。
您可以从代码中删除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()
返回的承诺的已解析值,因此它将被传递给该承诺的任何.then()
处理程序。当您将appendWord
作为.then()
处理程序传递时,这意味着该单词将被传递给appendWord
。并且,wala没有使用全局。