简体   繁体   English

Javascript睡眠x秒

[英]Javascript Sleep for x seconds

On my website I have a javascript function that does an AJAX call to get account's information then opens a modal where you can see and edit the information. 在我的网站上,我有一个javascript函数,该函数执行AJAX调用以获取帐户信息,然后打开一个模式,您可以在其中查看和编辑信息。 An AJAX call is used to change the detail in the database you select and then refreshes the original function to re-open the modal to refresh the information there. AJAX调用用于更改所选数据库中的详细信息,然后刷新原始功能以重新打开模式以刷新那里的信息。 It seems however, that occasionally (1/2+ times done) the details don't update fast enough in the DB before the functions that collects the details to display is run again. 但是,似乎在某些情况下(完成了1/2次以上),详细信息在数据库中更新的速度不够快,然后再次运行收集要显示的详细信息的功能。

I want to try delaying when the second function is ran to give a better chance for the details being updated before being fetched again, however I am unsure on how to do this. 我想尝试延迟第二个函数的运行时间,以便在再次获取之前为更新细节提供更好的机会,但是我不确定如何执行此操作。 I've tried various things, however the one that seems the most popular, as shown below, does not work. 我尝试了各种方法,但是如下所示,似乎最流行的方法不起作用。 Do you have any suggestions how I can fix it so the code pauses for x time before continuing? 您对我如何解决它有任何建议,以便代码在继续之前暂停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");
         }
     });
 }   

setTimeout() may behave as expected when function is wrapped in function(){ ... } 当函数包装在function(){ ... }时, setTimeout()行为可能与预期的一样

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

See here: JavaScript.setTimeout 看到这里: JavaScript.setTimeout

You could use the promise that $.ajax returns, which will have the then property. 您可以使用$.ajax返回的承诺,该承诺将具有then属性。 You can then pass a function to the then property which will only be called when the Ajax call has finished. 然后,您可以将一个函数传递给then属性,该函数仅在Ajax调用完成时才被调用。 So then you don't need a timeout anymore: 因此,您不再需要超时:

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

Then in your ChangeRank function you can make use of the above change: 然后,在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);
    });
}

Note that your timeout call was wrong anyway, since you did not pass a function reference to it, but executed ModeratorActions immediately. 请注意, timeout调用还是错误的,因为您没有传递函数引用给它,而是立即执行了ModeratorActions You could have used bind to pass the reference and still have the arguments passed to it when the actual call was made 30 seconds later: 您可以使用bind来传递引用,而在30秒后进行实际调用时仍将参数传递给它:

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

But this solution is still less practical compared to the promise-based solution, as the promise really fulfils when the Ajax transaction completes, and not a second later. 但是,与基于诺言的解决方案相比,该解决方案仍然不太实用,因为诺言在Ajax事务完成时才真正实现,而不会在第二秒后完成。

Why not move the function to reload the data into the success method of the function used to save it? 为什么不移动函数以将数据重新加载到用于保存数据的函数的成功方法中? Rather than hoping the save request will complete in 3 seconds? 而不是希望保存请求将在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); setTimeout(ModeratorActions(StrUsername,StrPage),30000);

It's not the correct way to pass arguments to the callback, in your case ModeratorActions will be invoked immediately, so that probably explains why it works unreliably, you should use the following syntax: 这不是将参数传递给回调的正确方法,在这种情况下, ModeratorActions将被立即调用,因此这可能解释了为什么它运行不可靠的原因,应使用以下语法:

setTimeout(ModeratorActions, 30000, StrUsername, StrPage)

Note: the above syntax passing additional arguments to callback function doesn't work for IE 9 and below, read setTimeout on Mozilla for workaround. 注意:上面的语法将其他参数传递给回调函数不适用于IE 9及以下版本,请在Mozilla上阅读setTimeout以获取解决方法。

EDIT: I should type more fast next time. 编辑:下次我应该键入更快。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM