【问题标题】:Multiple ajax calls on every call update the variable每次调用的多个 ajax 调用都会更新变量
【发布时间】:2018-08-23 17:55:18
【问题描述】:

在我的页面上,我有一个 ajax 脚本,它有一系列 ajax 调用嵌套在彼此的成功函数中,以便执行下一个。例如——

            $.ajax({
                data: {
                    action: 'polly_pros',
                    pollytext: text
                },
                type: 'post',
                url: polpro.ajax_url,
                cache: false,
                success: function(data) {
                    $('#player')[0].pause();
                    $('#player')[0].load();
                    var aud_dur = $('#aud_dur').val();
              // NEXT AJAX CALL                  
                    $.ajax({
                        data: {

在我的表单上我的隐藏输入--

<input type="hidden" name="aud_dur" id="aud_dur" value="" />

在我的页面上,每当加载音频文件时更新我隐藏的音频文件输入,我使用 --

var Aud = $('#player');
var aud_dur = $('#aud_dur');
Aud[0].addEventListener('loadeddata', function() {
    aud_dur.val($('#player')[0].duration);
});

在我的 php 脚本中,我试图这样检索值 --

$aud_dur = $_POST['aud_dur'];

我的隐藏输入在我的表单上更新得很好,但新值没有被发回,以便我可以在下一个 ajax 调用中使用它。现在似乎没有从变量发送任何数据。

有什么建议吗?

编辑

我的 ajax 代码中有几个调用在前一个调用成功后执行。

polly_pros ajax 调用创建一个音频文件,下面的 ajax 调用假设从那里获取音频持续时间,我也将其放入隐藏输入中。

如果文件已经存在,我可以获得持续时间,但如果动态创建文件(就像我需要做的那样),我无法获得持续时间值。

这是我的完整 ajax 代码(删除无关变量以简化)---

jQuery(document).on('click', '#make-vid', function(e) {
    e.preventDefault();
    var aud_dur;
    var pollytext = $('#pollytext').val();
    var path = $('#path').val();
    var post_id = $('#post_id').val();
    // AJAX CALL
    $.ajax({
        url: vformpro.ajax_url,
        data: {
            action: 'vform_pros',
            post_id: post_id,
        },
        type: 'POST',
        success: function(data) {
            console.log(data);
            var audio = $("#player");
            var post_id = $("#post_id").val();
            var aud_dur = $("#aud_dur").val();
            var tune_dur = $("#tune_dur").val();

            // AJAX CALL
            $.ajax({
                data: {
                    action: 'polly_pros',
                    post_id: post_id
                },
                type: 'post',
                url: polpro.ajax_url,
                cache: false,
                success: function(data) {
                    console.log(data);
                    $('#player')[0].pause();
                    $('#player')[0].load(function() {

                        // HERE I AM TRYING TO GET THE AUDIO DURATION UPON SUCCESS OF THIS AJAX CALL SO // THAT I CAN PASS IT TO THE FOLLOWING AJAX CALL

                        var Aud = $('#player');
                        var aud_dur = $('#aud_dur');
                        Aud[0].addEventListener('loadeddata', function() {
                            aud_dur.val($('#player')[0].duration);
                            console.log(aud_dur);
                        });

                    });
                    // AJAX CALL
                    $.ajax({
                        data: {
                            action: 'mvid_pros',
                            post_id: post_id,
                            aud_dur: aud_dur,
                            tune_dur: tune_dur
                        },
                        type: 'post',
                        url: mvidpro.ajax_url,
                        cache: false,
                        success: function(data) {
                            console.log(data);
                            $("#video-preview")[0].pause();
                            $("#video-preview")[0].load();
                        },
                        error: function() {
                            $('.load-text').text('Error on making Video.');
                        }
                    });
                },
                error: function(data) {
                    console.log(data);
                },
            });
        }
    });
});

更新

这是一个link to the full code (WIP),可以为我的问题提供更好的背景。

【问题讨论】:

  • 您的第二个 ajax 调用在您的播放器的加载数据事件之前开始,因此 var aud_dur = $('#aud_dur').val(); 行获取之前的值。尝试将 var aud_dur = $('#aud_dur').val(); 和您的第二个 ajax 调用放在 loaddeddata 事件处理程序中。
  • 当您调用 Ajax 调用时,JS 会在将值分配给 HTML 中的隐藏变量之前立即运行。有一种方法,如果你想在调用下一个ajax调用前加上一秒的settimeout(1000, passtheAJAXfunction(aud_val)),单独编写ajax调用函数,在第一次ajax调用成功时调用。
  • @vbRocks 请查看我更新的问题
  • 无论谁否决了我的问题,至少应该解释一下原因。
  • 那么我想我来对地方学习了,不是吗?我绝对不是 JS 开发人员,这是我第一次不得不一个接一个地运行 ajax 调用。

标签: javascript jquery ajax html5-audio


【解决方案1】:

(更新答案)

我仍然认为主要问题可能出在 $('#player')[0].load(function() {...}) 上,就像在 this 代码中一样。

我的意思是,如果具有playerid 的元素是audio 元素,那么您提供给该load() 方法的function 将永远不会被调用audio 元素。请注意$(selector).load()$(selector)[0].load() 不同——“选择器”可以是'#my_id''.my_class' 等。

但无论如何,请尝试this 代码,它是your 代码的完整 版本的优化 版本。

您可能无法简单地将您的代码与优化后的版本进行比较;但是,您应该不难发现主要变化,例如我使用单个 form_data 对象而不是大量变量,其中 form_data 存储您发送到 PHP 脚本的表单数据。

在优化后的代码中,您会发现执行第三个 AJAX 请求的代码(带有操作 mvid_pros):

function mvidPros() {
  var aud_dur = $('#player')[0].duration;
  console.log(aud_dur);

  // Set the value of the #aud_dur field.
  $("#aud_dur").val(aud_dur);

  // Initialize the data for the 'mvid_pros' AJAX call.
  var form_data = {
    action: 'mvid_pros',
    post_id: $("#post_id").val()
  };

  // Add input values to the data.
  form_data.songlink = $("#songlink").val();
  ...
  form_data.aud_dur = aud_dur;
  form_data.tune_dur = $("#tune_dur").val();
  ...

  $.ajax({
    'data': form_data,
    type: 'post',
    url: mvidpro.ajax_url,
    cache: false,
    //async:false,
    success: function(data) {
      console.log(data);
      ...
    },
    error: function() {
      $('.load-text').text('Error on making Video.');
    }
  });
}

下面是调用上述函数的代码:

$('#player')[0].pause();
$('#player').one('loadeddata', mvidPros);
$('#player')[0].load();

【讨论】:

  • 您能否在 Pastebin 上发布新代码(您的代码的完整版本,但带有我在回答中建议的替换代码)?我想看看,你用什么 PHP 库来实现 TTS 功能?
  • 别管插件了。我想我可能已经看到问题出在哪里了。我会尝试解决这个问题,稍后再回来。
  • 我已经更新了答案。您还可以查看this 并将其与this 进行比较,看看有什么变化。
  • 检查更新的答案。希望它会对您有所帮助,即使它可能无法准确回答问题。
  • 哇,谢谢!我尝试了你的代码,到目前为止它似乎正在工作。我必须对其进行更多测试以确保,但到目前为止还不错。到目前为止,您一直很有帮助!
【解决方案2】:

你的代码有问题,正确重构你的代码,你应该没问题:

P.S:我无法运行代码,因此请确保您正确地确定变量的范围,以使代码正常工作。

jQuery(document).on('click', '#make-vid', function(e) {
    e.preventDefault();
    var pollytext = $('#pollytext').val();
    var path = $('#path').val();
    var post_id = $('#post_id').val();
    var onAudioDataLoaded = function() {
        var aud_duration = $('#player')[0].duration;
        var tune_duration = $("#tune_dur").val();
        $('#aud_dur').val(duration);

        // AJAX CALL
        $.ajax({
            data: {
                action: 'mvid_pros',
                post_id: post_id,
                aud_dur: aud_duration,
                tune_dur: tune_duration
            },
            type: 'post',
            url: mvidpro.ajax_url,
            cache: false,
            success: onMvidProsSuccess,
            error: onMvidProsError
        });
    };
    var onMvidProsSuccess = function(data) {
        console.log(data);
        $("#video-preview")[0].pause();
        $("#video-preview")[0].load();
    };
    var onMvidProsError = function() {
        $('.load-text').text('Error on making Video.');
    };
    var onPolyProsError = function(data) {
        console.log(data);
    };
    var onPolyProsSuccess = function(data) {
        console.log(data);

        $('#player')[0].pause();
        $('#player')[0].load(function() {

            // HERE I AM TRYING TO GET THE AUDIO DURATION UPON SUCCESS OF THIS AJAX CALL SO // THAT I CAN PASS IT TO THE FOLLOWING AJAX CALL

            var Aud = $('#player');
            Aud[0].addEventListener('loadeddata', onAudioDataLoaded);
        });
    };
    var onFormPostSuccess = function(data) {
        console.log(data);
        // AJAX CALL
        $.ajax({
            data: {
                action: 'polly_pros',
                post_id: post_id
            },
            type: 'post',
            url: polpro.ajax_url,
            cache: false,
            success: onPolyProsSuccess,
            error: onPolyProsError
        });
    };
    // AJAX CALL
    $.ajax({
        url: vformpro.ajax_url,
        data: {
            action: 'vform_pros',
            post_id: post_id,
        },
        type: 'POST',
        success: onFormPostSuccess
    });
});

【讨论】:

  • ajax 调用应该按以下顺序 --- 1. vform_pros 2. polly_pros 3. mvid_pros .. 我不熟悉你的代码是如何设置的,所以我的问题是按那个顺序执行?
  • 它的执行顺序与您发布的代码相同。
  • 我已经尝试过您的建议,但在 polly_pro 通话后,它卡住了,无法进行下一次通话。
  • 您是否在控制台上看到任何错误/日志。成功时它会调用onPolyProsSuccess 函数,所以如果它卡住了,问题可能是该函数中的代码。
  • 我没有看到控制台上显示任何错误。我知道它卡在 pollypro 成功,因为“成功 console.log”来自该功能。
【解决方案3】:

您需要在发送到服务器的数据中包含您的aud_dur 值。没有调用表单提交方法,您正在执行 ajax 请求。

$.ajax({
    data: {
        action: 'polly_pros',
        pollytext: text,
        aud_dur : $('#aud_dur').val()
    },
.....

将您的数据对象更改为将其包含在您的帖子值中,您应该会看到它被发送到您的服务器。您可以通过在浏览器的开发控制台中检查网络请求来检查实际发送的内容。

根据您更新的问题,在分配您的 aud_dur 值之前,您的下一个 Ajax 调用正在运行。分配 aud_dur 变量后,将 Ajax 调用放在事件处理程序中

jQuery(document).on('click', '#make-vid', function(e) {
    e.preventDefault();
    var aud_dur;
    var pollytext = $('#pollytext').val();
    var path = $('#path').val();
    var post_id = $('#post_id').val();
    // AJAX CALL
    $.ajax({
        url: vformpro.ajax_url,
        data: {
            action: 'vform_pros',
            post_id: post_id,
        },
        type: 'POST',
        success: function(data) {
            console.log(data);
            var audio = $("#player");
            var post_id = $("#post_id").val();
            var aud_dur = $("#aud_dur").val();
            var tune_dur = $("#tune_dur").val();

            // AJAX CALL
            $.ajax({
                data: {
                    action: 'polly_pros',
                    post_id: post_id
                },
                type: 'post',
                url: polpro.ajax_url,
                cache: false,
                success: function(data) {
                    console.log(data);
                    $('#player')[0].pause();
                    $('#player')[0].load(function() {

                        // HERE I AM TRYING TO GET THE AUDIO DURATION UPON SUCCESS OF THIS AJAX CALL SO // THAT I CAN PASS IT TO THE FOLLOWING AJAX CALL

                        var Aud = $('#player');
                        var aud_dur = $('#aud_dur');
                        Aud[0].addEventListener('loadeddata', function() {
                            aud_dur.val($('#player')[0].duration);
                            console.log(aud_dur);
                            // AJAX CALL **MOVED**
                            $.ajax({
                                data: {
                                    action: 'mvid_pros',
                                    post_id: post_id,
                                    aud_dur: $('#aud_dur').val(),
                                    tune_dur: tune_dur
                                },
                                type: 'post',
                                url: mvidpro.ajax_url,
                                cache: false,
                                success: function(data) {
                                    console.log(data);
                                    $("#video-preview")[0].pause();
                                    $("#video-preview")[0].load();
                                },
                                error: function() {
                                    $('.load-text').text('Error on making Video.');
                                }
                            });
                        });

                    });


                },
                error: function(data) {
                    console.log(data);
                },
            });
        }
    });
});

【讨论】:

  • 音频持续时间值需要传递到我的下一个 ajax 调用到我的 php 函数
  • 你能举个例子吗?第一个示例似乎不正确,因为我需要 polly pro ajax 成功后的音频持续时间
  • @Rich 已更新。在您发送下一个 AJAX 请求之前,您的事件处理程序不会被触发。所以 aud_dur 值在使用之前没有被设置,所以它被作为 null 传递。
  • 我尝试了您的建议,但在 polly_pros 调用之后,它卡住并继续显示加载的 gif 和文本。
  • @Rich,我解决了一个问题,但您需要查看控制台等,查找并发布任何正在发生的错误,否则我们将不知道发生了什么.否则,您需要提供一个有效的 codepen 或能证明问题的东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-14
  • 1970-01-01
  • 2014-07-11
  • 1970-01-01
  • 2023-03-24
  • 2013-05-30
  • 1970-01-01
相关资源
最近更新 更多