【问题标题】:Waiting for ajax response same function等待ajax响应相同的功能
【发布时间】:2014-09-10 02:01:22
【问题描述】:

我知道类似的问题已经发布了很多次,但是我已经阅读了很多,但找不到我的问题的答案。

我有一个等待 ajax 请求响应的函数。很多人会问为什么?好吧,我正在使用一个向导 Jquery 插件,它在离开步骤时执行一个函数 onLeaveAStepFunction,然后如果来自 onLeaveAStepFunction 的返回值为真,向导将转到选定的步骤;否则它保持在同一步骤中。

我正在这样做 async: false 等待并且它有效,但这是一个糟糕的设计。另外,我不能使用 blockUI 插件。

我该怎么做?

一些代码:

初始化向导:

$("#wizard").smartWizard({
        onLeaveStep : onLeaveStepFunction,
    });

调用ajax请求:

function onLeaveStepCallback(obj, context) {
    nextStep = sendForm();
}

ajax 请求:

var nextStep = false;
$.ajax({
    url : path,
    type : "POST",
    async : false,
    data : $("#" + idForm).serialize(),
    success : function(data) {
        $("#" + idDiv).html(data);
        nextStep = !$("#" + idHiddenErrores).val())
    }
});

省略属性。请帮帮我。

【问题讨论】:

  • 你不能这样做,因为 ajax 的异步特性......
  • @Arun 那我怎样才能阻止 un 等待 ajax 响应呢?
  • @Arun 虽然 AJAX 本质上是异步的,但你不能在需要时执行阻塞的 AJAX 请求,这根本不是真的
  • @BrianBolli 那么它本质上不是异步的,不是吗...如果您使用的是异步请求,这是不可能的,但有一些方法可以使其同步但有成本...
  • 同意,但有一次我需要在执行警报之前执行一个被阻止的 AJAX 请求。我的断言只是可以做到,一定是误读了您的评论。 :)

标签: javascript jquery ajax smart-wizard


【解决方案1】:

您可以使用 jQuery 等待方法。我从文档页面举了一个例子来强调你是如何做到的:

$.when( $.ajax( "/request.php" ) ).done(function( response ) {
        // response argument resolved from ajax requests
        // process any work after ajax call finishes
}

文档页面的链接:

http://api.jquery.com/jquery.when/

【讨论】:

  • 智能向导 API 似乎不支持 Deferred 的,它期望立即返回值而不是承诺,所以如果他希望它在与该序列相同的位置执行,那么他有点不走运。
  • 没错,向导插件需要一个真或假的立即数
  • 为什么人们在$.when() 中封装一个ajax 调用。没有必要这样做。你可以直接做$.ajax().done()。在那里使用$.when() 根本没有任何好处,只需要等待一个 ajax 调用。
  • @prodigitalson:那么应该考虑使用一个 smarter 向导插件... :-)
  • @Bergi 完全同意......事实上,如果您不需要很多疯狂的功能或大量抽象,那么从头开始编写它可能会更容易,或者如果您需要这些功能,派生那个使用并修改回调以接受承诺 - 然后发出拉取请求。没有理由为什么那个东西不应该依赖事件和/或承诺,而不是在那里传递一个硬回调。我会称之为糟糕的设计。
【解决方案2】:

我正在做这个 async: false for waiting 并且它可以工作,但这是一个糟糕的设计,我也不能使用 blockUI 插件。

除非您的向导设计得更好并且支持异步回调(例如,返回承诺的回调),否则async:false 是您唯一的选择。

考虑切换到其他向导,不要忘记为您当前使用的插件提交错误。

【讨论】:

  • 不幸的是,添加块 ui 插件是一个后期要求。更换向导太贵了,但谢谢。
  • 如果无法选择完全不同的向导,请考虑分叉和修补当前插件。添加承诺支持应该是轻而易举的事。
  • 在ajax请求完成后出现块ui。我在 ajax 请求之前使用它,但它不起作用。我也尝试在 beforeSend 函数 jquery 中使用它
  • 您可以在 DOM 更新后对force a reflow 应用一些技巧,这可能会导致重绘。如果这不起作用(或在所有目标浏览器中都不起作用),那您就太不走运了 - 更改插件。
  • 哈哈哈我试试。谢谢。
【解决方案3】:

一个 hackish 解决方法是在 leaveStep 之前完成它。也许在 showStep 上:

var wizard_next_step;
$("#wizard").smartWizard({
    onShowStep : function (obj, context) {
        onLeaveStepFunction(obj, context, function(nextStep){
            wizard_next_step = nextStep;
        });
    },
    onLeaveStep : function () {
        return wizard_next_step;
    }
});

您还需要修改您的 onLeaveStepFunction 以接受回调:

function onLeaveStepCallback(obj, context, callback) {
    nextStep = sendForm(callback);
}

然后你的 ajax 函数应该是:

$.ajax({
    url : path,
    type : "POST",
    async : false,
    data : $("#" + idForm).serialize(),
    success : function(data) {
        $("#" + idDiv).html(data);
        callback( !$("#" + idHiddenErrores).val()) );
    }
});

现在,您似乎正在使用以下内容进入向导窗口:

$("#" + idDiv).html(data);

我完全确定是否是这种情况。但如果是这样,那么您不能在这里执行此操作(显然是因为 onShowStep 会覆盖当前内容)。如果是这样,您应该在回调中传递数据:

success : function(data) {
    callback( data , !$("#" + idHiddenErrores).val()) );
}

这样编写向导:

var wizard_next_step;
var wizard_data;
$("#wizard").smartWizard({
    onShowStep : function (obj, context) {
        onLeaveStepFunction(obj, context, function(data, nextStep){
            wizard_data = data;
            wizard_next_step = nextStep;
        });
    },
    onLeaveStep : function (obj, context) {
        $("#" + idDiv).html(wizard_data);
        return wizard_next_step;
    }
});

关键是在调用所有同步函数之前调用所有异步函数并获取数据。

注意:我根本不了解 smart-wizard,也不是一个认真的 jQuery 用户。上面的答案是基于我在 github 上阅读 smart-wizard 文档的 2 分钟以及我对 javascript 的理解。您肯定需要修改我的示例以使其正常工作。

【讨论】:

    猜你喜欢
    • 2013-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-24
    • 1970-01-01
    • 1970-01-01
    • 2011-09-09
    • 1970-01-01
    相关资源
    最近更新 更多