暂停函数执行流程,直到 ajax 请求完成
Posted
技术标签:
【中文标题】暂停函数执行流程,直到 ajax 请求完成【英文标题】:Pause the function execution flow till ajax request completes 【发布时间】:2016-09-08 12:07:48 【问题描述】:我似乎遇到了典型的“异步问题”,而我却找不到解决方案。
我有一个bootstrap form wizard,它只是一个临时的标签/幻灯片有点东西。我所有的“步骤”都是各自标签/幻灯片中的表格。
它有一组下一个/上一个按钮来浏览幻灯片。 并且它在移动到下一张幻灯片之前提供了一个函数回调。 在其中(回调)我正在“客户端验证”当前幻灯片中的表单,如果它经过验证,那么我将使用 ajax 提交表单。一旦我得到服务器的响应,我将决定是返回 true(继续下一张幻灯片)还是返回 false(停止导航到下一张幻灯片)。
我已经调查了..
Using callbacks 但它不会阻止插件继续到下一张幻灯片,顺便说一句,这是一个硬编码的成功消息,所以在我们等待 ajax 响应时,向导已经移动到下一张幻灯片。 使用async:false
但这会像疯了一样挂起浏览器(按设计),直到请求完成,所以没有挂起这正是我想要的。
我的代码如下。
JS.
jQuery('#progressWizard').bootstrapWizard(
'nextSelector': '.next',
'previousSelector': '.previous',
onNext: function (tab, navigation, index)
if (index == 1) // Here I am deciding which code to execute based on the current slide/tab (index)
if (jQuery("#paymentstep1").data('bValidator').validate())
var data = new FormData(jQuery('#paymentstep1')[0]);
jQuery("#cgloader").fadeIn();
var success = false;
jQuery.ajax(
type: "post",
async: false,
contentType: false,
processData: false,
url: "xyz.php",
dataType: "json",
data: data,
success: function (r)
return r;
);
....
【问题讨论】:
第一种方法是唯一真正可接受的解决方案。如果这意味着更改向导插件,我仍然强烈推荐它。使用async: false
绝不是一种选择,因为正如您所见,它会挂起浏览器直到请求完成。这将使浏览器在用户看来就像崩溃一样,这是糟糕的用户体验。解决方法是使用异步请求。
停止导航到下一张幻灯片,然后在回调时重新启动
【参考方案1】:
docs 对 onNext
说:
单击下一个按钮时触发(返回 false 以禁用 进入下一步)
所以只需从您的处理程序返回false
。在 AJAX 成功回调中,调用next
前进到下一张幻灯片。
var requestCompleted = false;
jQuery('#progressWizard').bootstrapWizard(
'nextSelector': '.next',
'previousSelector': '.previous',
onNext: function (tab, navigation, index)
if (index == 1) // Here I am deciding which code to execute based on the current slide/tab (index)
if (jQuery("#paymentstep1").data('bValidator').validate())
if(!requestCompleted)
var data = new FormData(jQuery('#paymentstep1')[0]);
jQuery("#cgloader").fadeIn();
var success = false;
jQuery.ajax(
type: "post",
url: "xyz.php",
data: data,
// ...
success: function (r)
requestCompleted = true;
jQuery('#progressWizard').bootstrapWizard('next');
return r;
);
return false;
);
【讨论】:
但是如果我在ajax中调用next成功,“onNext”回调中的代码不会再次被触发吗?再次发出 ajax 请求? 当然。因此,请使用变量来跟踪您是否已发出请求。 hm... tbh,我一直牢记这一点,但不确定这是否是正确的方法,所以如果我找不到更好的解决方案。谢谢。【参考方案2】:使用承诺?
在 jQuery 中有一个承诺。这是语法。
$.when( $.ajax( "test.aspx" ) ).then(function( data, textStatus, jqXHR )
alert( jqXHR.status ); );
现在在 javascript 中也有了 Promise!
var promise = new RSVP.Promise(function(fulfill, reject)
(...)
);
那么,
promise.then(onFulfilled, onRejected);
【讨论】:
谢谢克里斯克拉克!那个承诺代码救了我的培根!【参考方案3】:我会使用不同的事件来执行您的异步代码。这个想法是使用 onTabChange
(考虑使用 onTabClick
和 onTabShow
),这样你就可以防止移动到下一个选项卡 bootstrapWizard();
将如何导航。只有在一切通过后,才能以编程方式触发下一个选项卡,您必须了解如何操作。
$('element').bootstrapWizard('onTabShow', function()
//Do everything you need here and show next tab
$('element').bootstrapWizard('show',3);
return false;
);
【讨论】:
以上是关于暂停函数执行流程,直到 ajax 请求完成的主要内容,如果未能解决你的问题,请参考以下文章
redux-thunk:暂停组件执行,直到 Action Creator 完成