JQuery.when() 和 then() 不适用于异步事件
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 为全局变量 chosenWord 获取相同的值?我不明白为什么 when() 和 then() 函数在我的代码中不起作用。
你必须returnwordFromFile()
中的承诺。
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
值成为承诺的已解析值,那么您应该 return 它来自 .then()
处理程序。另外,请注意,我将 $.get()
上的回调更改为 .then()
处理程序,以使事情更加一致。通常,一旦您使用了 promise,您就希望在操作中始终如一地使用它们,而不是在 promise 中混合使用老式的回调。这样做会破坏 promises 提供的一些自动错误传播和错误处理功能。
然后,您根本不需要在 setRandomWord()
中使用 $.when()
因为 wordFromFile()
已经 return 是一个承诺,您需要将函数引用传递给.then()
appendWord 后没有括号:
function setRandomWord() {
wordFromFile("http://mypage.com/words.txt").then(appendWord);
}
回顾一下:
- Return
wordFromFile()
的承诺
- 在
wordFromFile()
中使用 .then()
处理程序而不是 jQuery 回调。
- 删除
wordFromFile()
左右的 $.when()
,因为不需要。
- 将函数引用传递给
.then()
时,移除 appendWord
后的括号。您采用的方式是立即调用 appendWord,而不是让 .then()
处理程序稍后在 promise 解析时调用它。
- 你的随机数逻辑不太正确,除非你总是试图避免第一个词。
请记住,承诺没有魔力。当它们内部的异步操作以某种方式完成时,它们不会 "know"。当异步操作手动解决承诺时,他们只知道异步操作何时完成。因此,您不能只在 $.when()
中放置一些异步操作并期望 $.when()
神奇地知道异步操作何时完成(很多人都尝试过这个,所以显然这是人们对 promises 不熟悉的东西似乎在期待)。相反,您将承诺传递给 $.when()
并且异步操作必须解决这些承诺。在您的情况下,您只有一个承诺,因此不需要 $.when()
。通常只有当您有多个要等待的承诺时才需要它。当你只有一个承诺时,你可以只调用 .then()
就可以了。
其他注意事项:
- 您正在使用全局变量
chosenWord
来传回结果。这不是必需的,通常被认为是一种反模式。
- 您的 ajax 调用没有任何错误处理。
此代码:
$(function() {
if($('body').is('.playpage')) {
setRandomWord();
}
});
可以简化为:
$(function() {
$("body.playpage").each(setRandomWord);
});
如果 body 标签上有 playpage
class,那么它将调用 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()
return 承诺的解析值,因此它将被传递给任何 .then()
承诺的处理程序。当您将 appendWord
作为 .then()
处理程序传递时,这意味着该词将为您传递给 appendWord
。而且,wala 没有使用全局。
我正在尝试从文本文件中读取行,从文件中选择一行并将其插入到 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 为全局变量 chosenWord 获取相同的值?我不明白为什么 when() 和 then() 函数在我的代码中不起作用。
你必须returnwordFromFile()
中的承诺。
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
值成为承诺的已解析值,那么您应该 return 它来自 .then()
处理程序。另外,请注意,我将 $.get()
上的回调更改为 .then()
处理程序,以使事情更加一致。通常,一旦您使用了 promise,您就希望在操作中始终如一地使用它们,而不是在 promise 中混合使用老式的回调。这样做会破坏 promises 提供的一些自动错误传播和错误处理功能。
然后,您根本不需要在 setRandomWord()
中使用 $.when()
因为 wordFromFile()
已经 return 是一个承诺,您需要将函数引用传递给.then()
appendWord 后没有括号:
function setRandomWord() {
wordFromFile("http://mypage.com/words.txt").then(appendWord);
}
回顾一下:
- Return
wordFromFile()
的承诺
- 在
wordFromFile()
中使用.then()
处理程序而不是 jQuery 回调。 - 删除
wordFromFile()
左右的$.when()
,因为不需要。 - 将函数引用传递给
.then()
时,移除appendWord
后的括号。您采用的方式是立即调用 appendWord,而不是让.then()
处理程序稍后在 promise 解析时调用它。 - 你的随机数逻辑不太正确,除非你总是试图避免第一个词。
请记住,承诺没有魔力。当它们内部的异步操作以某种方式完成时,它们不会 "know"。当异步操作手动解决承诺时,他们只知道异步操作何时完成。因此,您不能只在 $.when()
中放置一些异步操作并期望 $.when()
神奇地知道异步操作何时完成(很多人都尝试过这个,所以显然这是人们对 promises 不熟悉的东西似乎在期待)。相反,您将承诺传递给 $.when()
并且异步操作必须解决这些承诺。在您的情况下,您只有一个承诺,因此不需要 $.when()
。通常只有当您有多个要等待的承诺时才需要它。当你只有一个承诺时,你可以只调用 .then()
就可以了。
其他注意事项:
- 您正在使用全局变量
chosenWord
来传回结果。这不是必需的,通常被认为是一种反模式。 - 您的 ajax 调用没有任何错误处理。
此代码:
$(function() {
if($('body').is('.playpage')) {
setRandomWord();
}
});
可以简化为:
$(function() {
$("body.playpage").each(setRandomWord);
});
如果 body 标签上有 playpage
class,那么它将调用 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()
return 承诺的解析值,因此它将被传递给任何 .then()
承诺的处理程序。当您将 appendWord
作为 .then()
处理程序传递时,这意味着该词将为您传递给 appendWord
。而且,wala 没有使用全局。