Javascript Sleep for x seconds



在我的网站上,我有一个javascript函数,它执行AJAX调用以获取帐户信息,然后打开一个模式,您可以在其中查看和编辑信息。AJAX 调用用于更改所选数据库中的详细信息,然后刷新原始函数以重新打开模式以刷新其中的信息。但是,似乎偶尔(完成 1/2+ 次)在再次运行收集要显示的详细信息的函数之前,数据库中的详细信息更新速度不够快。

我想尝试延迟第二个函数的运行时间,以便在再次获取之前更好地更新详细信息,但是我不确定如何做到这一点。我已经尝试了各种方法,但是看起来最受欢迎的一种(如下所示)不起作用。您有什么建议如何修复它,以便代码在继续之前暂停 x 时间吗?

function ChangeRank(StrUsername, StrPage)
{
var StrRank = $("#sltRank option:selected").val();
//Updates info in database
ModeratorEditAccount(StrUsername, StrRank, 'Rank', StrPage);
//Displays info again
setTimeout(ModeratorActions(StrUsername, StrPage), 30000);
}
function ModeratorEditAccount(StrUsername, Value, StrDetail, StrPage)
{
$.post('http://thomas-smyth.co.uk/functions/php/fncmoderatoreditaccount.php',
{
StrUsername: StrUsername,
Value: Value,
StrDetail: StrDetail
}, function(data)
{
if (data == 0)
{
$("#mdlGeneral > div").modal("hide");
if (StrSearchType == "Basic")
{
UserBasicSearch(StrPage);
}
else
{
UserAdvanceSearch(StrPage);
}
}
else if (data == 10)
{
window.location.href = "http://thomas-smyth.co.uk/login.php";
}
});
}
function ModeratorActions(StrUsername, StrPage)
{
$.post('http://thomas-smyth.co.uk/functions/php/fncgetaccountdetails.php',
{
StrUsername: StrUsername
}, function(data)
{
var returnValue = JSON.parse(data);
if (data == 5)
{}
else
{
if (returnValue["StrGender"] == "M")
{
StrGender = "Male";
}
else
{
StrGender = "Female";
}
$("#mdlEditProfile").html('<div class="modal" tabindex="-1" role="dialog"><div class="modal-dialog" role="document"><div class="modal-content" style="border-radius: 25px;"><div class="box box-widget widget-user-2"><div class="widget-user-header bg-yellow"><div class="widget-user-image"><img class="img-circle" src="../dist/img/user2-160x160.jpg" alt="User Avatar"></div><h3 class="widget-user-username">' + returnValue['StrSurname'] + ', ' + returnValue['StrForename'] + ' (' + returnValue['StrUsername'] + ')</h3><h5 class="widget-user-desc">Member Since: ' + returnValue['DteRegDate'] + '</h5></div><div class="box-footer no-padding"><ul class="nav nav-stacked"><li><a><strong>Name: </strong>' + returnValue['StrSurname'] + ', ' + returnValue['StrForename'] + '<span class="pull-right badge bg-blue" style="cursor: pointer;" onclick="ChangeNameOpen('' + returnValue['StrUsername'] + '', '' + returnValue['StrSurname'] + '', '' + returnValue['StrForename'] + '', '' + StrPage + '')"><i class="fa fa-fw fa-edit"></i> Edit</span></a></li><li><a><strong>Username: </strong>' + returnValue['StrUsername'] + '<span class="pull-right badge bg-blue" style="cursor: pointer;" onclick="ChangeUsernameOpen('' + returnValue['StrUsername'] + '')"><i class="fa fa-fw fa-edit"></i> Edit</span></a></li><li><a><strong>Date of Birth: </strong>' + returnValue['DteDoB'] + '<span class="pull-right badge bg-blue" style="cursor: pointer;" onclick="ChangeDoBOpen('' + returnValue['StrUsername'] + '', '' + returnValue['DteDoB'] + '')"><i class="fa fa-fw fa-edit"></i> Edit</span></a></li><li><a><strong>Gender: </strong>' + returnValue['StrGender'] + '<span class="pull-right badge bg-blue" style="cursor: pointer;" onclick="ChangeGenderOpen('' + returnValue['StrUsername'] + '')"><i class="fa fa-fw fa-edit"></i> Edit</span></a></li><li><a><strong>Account Rank: </strong>' + returnValue['StrRank'] + '<span class="pull-right badge bg-blue" style="cursor: pointer;" onclick="ChangeRankOpen('' + returnValue['StrUsername'] + '', '' + returnValue['StrRank'] + '', '' + StrPage + '')"><i class="fa fa-fw fa-edit"></i> Edit</span></a></li></ul></div></div></div></div></div>');
$("#mdlEditProfile > div").modal("show");
}
});
}   

当函数包装在function(){ ... }中时,setTimeout()的行为可能符合预期

setTimeout( function(){ ModeratorActions(StrUsername, StrPage) }, 30000);

看这里: JavaScript.setTimeout

您可以使用$.ajax返回的承诺,这将具有then属性。然后,您可以将函数传递给then属性,该函数仅在 Ajax 调用完成后调用。因此,您不再需要超时:

function ModeratorEditAccount(StrUsername, Value, StrDetail, StrPage)
{
// Return the promise to the caller 
return $.post('http://thomas-smyth.co.uk/functions/php/fncmoderatoreditaccount.php',
/// etc ...
}

然后在您的ChangeRank函数中,您可以使用上述更改:

function ChangeRank(StrUsername, StrPage)
{
var StrRank = $("#sltRank option:selected").val();
//Updates info in database
ModeratorEditAccount(StrUsername, StrRank, 'Rank', StrPage).then(function () { 
// This only executes when previous ajax has returned
//Displays info again
ModeratorActions(StrUsername, StrPage);
}, function () {
// an error occurred, like a timeout.
ModeratorActions(StrUsername, StrPage);
});
}

请注意,您的timeout调用无论如何都是错误的,因为您没有向其传递函数引用,而是立即执行ModeratorActions。您可以使用bind传递引用,并且在 30 秒后进行实际调用时仍然将参数传递给它:

setTimeout(ModeratorActions.bind(null, StrUsername, StrPage), 30000);

但与基于承诺的解决方案相比,这种解决方案仍然不太实用,因为当 Ajax 事务完成时,而不是一秒钟后,承诺才真正实现。

为什么不将函数重新加载数据移动到用于保存它的函数的成功方法中?而不是希望保存请求在 3 秒内完成?

function ChangeRank(StrUsername, StrPage)
{
var StrRank = $("#sltRank option:selected").val();
//Updates info in database
ModeratorEditAccount(StrUsername, StrRank, 'Rank', StrPage);
//Displays info again
// Removed
//setTimeout(ModeratorActions(StrUsername, StrPage), 30000);
}
function ModeratorEditAccount(StrUsername, Value, StrDetail, StrPage)
{
$.post('http://thomas-smyth.co.uk/functions/php/fncmoderatoreditaccount.php',
{
StrUsername: StrUsername,
Value: Value,
StrDetail: StrDetail
}, function(data)
{
if (data == 0)
{
$("#mdlGeneral > div").modal("hide");
if (StrSearchType == "Basic")
{
UserBasicSearch(StrPage);
}
else
{
UserAdvanceSearch(StrPage);
}
// Added here, though you may want to move it
ModeratorActions(StrUsername, StrPage)
}
else if (data == 10)
{
window.location.href = "http://thomas-smyth.co.uk/login.php";
}
});
}
function ModeratorActions(StrUsername, StrPage)
{
$.post('http://thomas-smyth.co.uk/functions/php/fncgetaccountdetails.php',
{
StrUsername: StrUsername
}, function(data)
{
var returnValue = JSON.parse(data);
if (data == 5)
{}
else
{
if (returnValue["StrGender"] == "M")
{
StrGender = "Male";
}
else
{
StrGender = "Female";
}
$("#mdlEditProfile").html('<div class="modal" tabindex="-1" role="dialog"><div class="modal-dialog" role="document"><div class="modal-content" style="border-radius: 25px;"><div class="box box-widget widget-user-2"><div class="widget-user-header bg-yellow"><div class="widget-user-image"><img class="img-circle" src="../dist/img/user2-160x160.jpg" alt="User Avatar"></div><h3 class="widget-user-username">' + returnValue['StrSurname'] + ', ' + returnValue['StrForename'] + ' (' + returnValue['StrUsername'] + ')</h3><h5 class="widget-user-desc">Member Since: ' + returnValue['DteRegDate'] + '</h5></div><div class="box-footer no-padding"><ul class="nav nav-stacked"><li><a><strong>Name: </strong>' + returnValue['StrSurname'] + ', ' + returnValue['StrForename'] + '<span class="pull-right badge bg-blue" style="cursor: pointer;" onclick="ChangeNameOpen('' + returnValue['StrUsername'] + '', '' + returnValue['StrSurname'] + '', '' + returnValue['StrForename'] + '', '' + StrPage + '')"><i class="fa fa-fw fa-edit"></i> Edit</span></a></li><li><a><strong>Username: </strong>' + returnValue['StrUsername'] + '<span class="pull-right badge bg-blue" style="cursor: pointer;" onclick="ChangeUsernameOpen('' + returnValue['StrUsername'] + '')"><i class="fa fa-fw fa-edit"></i> Edit</span></a></li><li><a><strong>Date of Birth: </strong>' + returnValue['DteDoB'] + '<span class="pull-right badge bg-blue" style="cursor: pointer;" onclick="ChangeDoBOpen('' + returnValue['StrUsername'] + '', '' + returnValue['DteDoB'] + '')"><i class="fa fa-fw fa-edit"></i> Edit</span></a></li><li><a><strong>Gender: </strong>' + returnValue['StrGender'] + '<span class="pull-right badge bg-blue" style="cursor: pointer;" onclick="ChangeGenderOpen('' + returnValue['StrUsername'] + '')"><i class="fa fa-fw fa-edit"></i> Edit</span></a></li><li><a><strong>Account Rank: </strong>' + returnValue['StrRank'] + '<span class="pull-right badge bg-blue" style="cursor: pointer;" onclick="ChangeRankOpen('' + returnValue['StrUsername'] + '', '' + returnValue['StrRank'] + '', '' + StrPage + '')"><i class="fa fa-fw fa-edit"></i> Edit</span></a></li></ul></div></div></div></div></div>');
$("#mdlEditProfile > div").modal("show");
}
});
}   

setTimeout(ModeratorActions(StrUsername, StrPage), 30000);

这不是将参数传递给回调的正确方法,在您的情况下ModeratorActions将立即调用,因此这可能解释了为什么它不可靠,您应该使用以下语法:

setTimeout(ModeratorActions, 30000, StrUsername, StrPage)

注意:上述语法将其他参数传递给回调函数不适用于 IE 9 及更低版本,请阅读 Mozilla 上的 setTimeout 以获取解决方法。

编辑:下次我应该打得更快。

最新更新