支持一个令人困惑的解释。我正在制作一个愚蠢的小测验网站。页面上有五个问题。存储在xml文件中的答案。问题会随时向玩家显示,并提供输入以供他们回答。当玩家猜测某个特定答案时,JQuery会将猜测发布到一个php文件,该文件根据xml中存储的内容检查答案,并返回1(正确)和/或0(错误)。帖子由文本输入的keyup事件触发。
我有一个名为剩余的全局数组,用于存储仍待回答的页面上的问题。这是在页面加载时使用值[1,2,3,4,5]填充的。正确回答问题后,将删除相应的数字。因此,如果玩家回答问题1,剩余将包含[2,3,4,5]。
var current;
var remaining;
$(document).ready(function() {
// What question the player is on.
current = 1;
// Questions unanswered.
remaining = new Array(1, 2, 3, 4, 5);
$('#in').keyup(function() {
// Send answer to server to check if it's right.
CheckGuess($(this).val());
});
});
function CheckGuess(guess) {
if (guess.length > 2 && guess.length < 100)
{
$.post(
"class/check.php",
"current=" + current + "&answer=" + guess,
function(check) {
if (check == 1) {
AnswerCorrect();
}
},
"json"
);
}
}
function AnswerCorrect() {
// User guessed correctly.
if (remaining.length != 1) {
var next;
// Remove complete question from array of remaining values.
for (var i = 0; i < remaining.length; i++ ) {
if (remaining[i] == current) {
// Set the next question. It will be the next one in the array
// or the previous if the current question is the last in the array.
if (i != (remaining.length - 1)) {
next = remaining[i + 1];
} else {
next = remaining[i - 1];
}
debugger;
// Remove current question.
remaining.splice(i, 1);
// Get out of the for loop.
break;
}
}
// Set current as next.
current = next;
// Set the href for the next question.
var destination = "#m" + next;
// Scroll to next question.
$.scrollTo($(destination), { duration: 1000});
// Clear input box.
$("#in").val("");
}
else {
// Quiz complete.
}
}
这一切都在某种程度上起作用。但是我遇到了一些神秘的问题。我已经使用FireBug逐步完成了它,似乎发生了什么:
我希望我的解释有点清楚。在我的生活中,我从未理解过任何东西。我不明白上面的(b)和(c)点之间发生了什么。我正在逐步完成代码,但我无法找到剩余丢弃“2”的位置。 FireBug让我失望。它应该在某个地方似乎没有破坏。如果我在 split()上有断点,我看不到2的删除可能会在没有我看到的情况下继续。有人有任何线索吗?在我发疯之前,我真的很感激你的帮助。
编辑 - 更多信息
(对不起,答复很慢,我整天都在上班。)
真正的问题是我无法看到 2 被删除的位置。我想到的一件事可能就是问题(但是我不太了解Javascript是否有可能):
jQuery帖子经常发布;每次玩家输入一封信。是否有可能同时多次调用 AnswerCorrect()?那么 AnswerCorrect()的两个或多个“实例”同时运行?
编辑2
我决定放弃这种方法。我无法弄清楚这个问题。我重写了它,以便现在帖子发生在文档加载上,答案存储在服务器端的数组中。无论如何,这可能是一种更好的方式,因为我只有一个帖子到服务器而不是很多。现在一切正常。考虑这个线程已解决。
答案 0 :(得分:0)
我认为你的事情过于复杂。不需要循环或拼接,并且在循环中,您将数组索引与数组值混合以试图找出您的位置。这非常令人困惑 - 即使你已经弄明白了,下一个出现并保持下去的人也会丢失(即使那是你从现在开始的6个月)。
您希望第一个项目离开数组,并且您希望相应地修改数组长度。为此,您应该使用Array.prototype.shift()
。我已经重新安排了一些代码以获得更好的实践,但是试图将其中一些代码保留在相同的布局中,以避免让它无法识别:
var remaining = [ 1, 2, 3, 4, 5 ];
$( function()
{
$( '#in' ).keyup( function()
{
// Send answer to server to check if it's right.
CheckGuess( $( this ).val() );
} );
Next();
} );
function CheckGuess( guess )
{
if( guess.length > 2 && guess.length < 100 )
{
$.post(
'class/check.php',
{
current: + current,
answer + guess
},
function( check )
{
if( check == 1 )
{
Next();
}
},
'json'
);
}
}
function Next()
{
// User guessed correctly.
if( remaining.length )
{
current = remaining.shift();
// Scroll to next question.
$.scrollTo( $( '#m' + current ), { duration: 1000 } );
// Clear input box.
$( '#in' ).val( '' );
}
else
{
// Quiz complete.
}
}
答案 1 :(得分:0)
我老实说,您发布的代码中没有任何逻辑错误。我将它放在jsFiddle here中,模拟异步检查是正确的,每次都查看剩余的答案。它似乎对我有用。所以,如果您的真实代码是您正在讨论的问题,那么代码中必须有其他内容,您没有在此处向我们展示过。
在具有异步ajax调用的应用程序中,事情可能出错的一个典型位置是这样,并且某些全局状态是异步部分可能无法正确完成。在更改任何状态之前,必须等待服务器调用的成功处理程序。如果在处理之前状态发生了变化,那么当它完成时它可能会搞砸。
如果您可以假设数组中的第一个问题始终是正在处理的问题,那么其他两个答案建议的是更简单的编写代码的方法。您的AnswerCorrect()
代码并不假设唯一正在处理的答案是数组中的第一个,因此更通用,所以如果是这种情况,那么我认为您不能使用其他代码答案。
所以,我认为你的问题的答案是,导致错误的原因必须多于你在问题中披露的内容,因为我没有看到你发布的内容和“模拟”的任何严重的逻辑错误“jsFiddle使用你的代码似乎工作。那么,你的应用中还有什么东西没有在这里展示给我们?
修改强>
首次使用ajax调用时最常见的错误与ajax调用的异步性质有关。当你进行调用时,它会启动ajax调用,它会在后台发生,而其余的代码会继续运行。直到调用完成/成功函数之后的某个时间才完成。如果你忘记了这个事实,并且在你完成之前启动ajax调用后你做了其他事情,那么你的逻辑就会出错。你在这里发布的样本没有那个问题,但是我猜想在POST到服务器后你的实际代码还有更多,也许这就是错误/混淆的根源。由于您使用一些全局变量来跟踪状态,如果在POST调用之后和调用完成函数之前触摸任何这些全局变量(比如转到下一个问题),它将搞乱你的逻辑。成功功能将通过,您的全局状态将被错误地更改。这只是一个猜测,因为我必须经历的是您发布的代码,它没有您遇到的问题。
如果你想发布真实的代码或给我们一个真实页面的链接,我们可以看看那里。