首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在jQuery Ajax循环中延迟PHP函数的触发?

如何在jQuery Ajax循环中延迟PHP函数的触发?
EN

Stack Overflow用户
提问于 2018-12-18 00:16:38
回答 4查看 429关注 0票数 2

我有一个PHP脚本,临时上传CSV。重新加载一页CSV数据是从$_FILES获取的,并转换为JSON数组。

然后,我使用$.each遍历CSV行。

对于每一行,我对PHP函数执行一次AJAX调用,该函数设置一些订单跟踪数据并发送一封电子邮件。

由于电子邮件的限制,我想在每次循环迭代之间添加一个延迟。不过,我曾尝试在JavaScript中设置超时,但这并不起作用,我还试图在发送电子邮件之前添加一个PHP睡眠函数。

两种方法都不起作用,电子邮件仍然可以同时发送,没有延迟。

不管我添加的延迟如何,我发出的所有请求似乎都在一次处理中。

如何确保电子邮件发送延迟?

jQuery ($csv_rows是刚刚上传的CSV数据)

代码语言:javascript
复制
<script>

    // Get CSV Rows into JSON array

    var csvRows = '<?php echo json_encode( $csv_rows ); ?>';
    var csvRows = ( jQuery.parseJSON( csvRows ) );

    // Loop through each row

    $.each( csvRows, function( key, value ) {

        // Split row into array exploded by comma

        row = value.toString().split( ',' );

        // Get column values

        order = row[0];
        courier = row[1];
        tracking = row[2];

        // AJAX

        var data = {
            'action': 'shd_tracking_import',
            'order': order,
            'courier': courier,
            'tracking': tracking,
        };

        // Do the ajax

        $.ajax({
            url: ajaxurl,
            type: 'POST',
            data: data,
            success: function( response ) {
                $( '#shd-import-results p' ).hide();
                if( response !== '0' ) {
                    $( '#shd-import-results ul' ).append( response );
                    importedCount = parseInt( $( '#shd-import-progress span' ).text() );
                    $( '#shd-import-progress span' ).text( importedCount + 1 );
                } else {
                    $( '<p>Error importing. Please ensure CSV meets requirements.</p>' ).appendTo( '#shd-import-results' );
                }
            }
        });

    });

</script>

PHP (这是AJAX中引用的shd_tracking_import操作)

代码语言:javascript
复制
if( isset( $_POST['order'] ) && isset( $_POST['courier'] ) && isset( $_POST['tracking'] ) ) {

    // Delay (due to their Office 365 limits)

    usleep( 4000000 ); // 4 Seconds (usleep used as sleep cannot contain fractions, usleep is microseconds, this was 2.5 seconds hence using usleep)

    // My mailing function is here (which works just not delayed)

    echo 'Done';

} else {

    echo '0';

}

exit;
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2018-12-18 18:50:42

看过答案后,我决定以不同的方式看待这个问题,因为我不想使用会话,也不能在$.each上使用.promise()。因此,我将代码重写为以下代码。

这是通过从CSV获得总行数,运行AJAX一次,然后在ajax上使用.done()重新运行AJAX调用,直到它遍历了所有行,这就像我想要的那样工作。

代码语言:javascript
复制
<script>

    // Get CSV Rows into JSON array

    var csvRows = '<?php echo json_encode( $csv_rows ); ?>';
    var csvRows = ( jQuery.parseJSON( csvRows ) );
    var totalRows = csvRows.length - 1; // Minus 1 as starts 1, we need to start from 0 (e.g. for 4 rows this returns 4, when row 4 is actually 3 as starts from 0)

    // Do AJAX function

    function doAjax( $row ) {

        // Error

        var error = false;

        // Get row data

        order = csvRows[row][0];
        courier = csvRows[row][1];
        tracking = csvRows[row][2];

        // AJAX

        var data = {
            'action': 'shd_tracking_import',
            'order': order,
            'courier': courier,
            'tracking': tracking,
        };

        // Do the ajax

        $.ajax({
            url: ajaxurl,
            type: 'POST',
            data: data,
            success: function( response ) {
                $( '#shd-import-results p' ).hide();
                if( response !== '0' ) {
                    $( '#shd-import-results ul' ).append( response );
                    importedCount = parseInt( $( '#shd-import-progress span' ).text() );
                    $( '#shd-import-progress span' ).text( importedCount + 1 );
                } else {
                    error = true;
                }
            }
        }).done( function() {

            if( error !== true ) {

                // When AJAX is done

                var dt = new Date();
                var time = dt.getHours() + ":" + dt.getMinutes() + ":" + dt.getSeconds();

                // Row number total

                row = row + 1;

                // If row number is less than or equal to the total row count, if not do nothing, no further call.

                if( row <= totalRows ) {

                    console.log( 'Next AJAX about to run @ ' + time );
                    doAjax( row );

                } else {

                    $( '<span> - Import complete.</span>' ).appendTo( '#shd-import-progress' );

                }

            } else {

                $( '<span> - Import failed, check CSV meets requirements.</span>' ).appendTo( '#shd-import-progress' );

            }

        });

    }

    // Start row at zero

    row = 0;

    // Do Ajax (once row is done next row will run same AJAX function until all rows done)

    doAjax( row );

</script>
票数 0
EN

Stack Overflow用户

发布于 2018-12-18 00:20:32

您可以在jquery中使用promises,当应用程序接口执行完成时,promise代码将执行。

请参见示例

代码语言:javascript
复制
var div = $( "<div>" );

div.promise().done(function( arg1 ) {
  // Will fire right away and alert "true"
  alert( this === div && arg1 === div );
});
票数 1
EN

Stack Overflow用户

发布于 2018-12-18 00:34:30

您的脚本同时运行所有实例,所有这些实例都会延迟4秒,但都是异步的。

您的延迟应该在JavaScript中,以便每4秒调用一次PHP文件。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53819073

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档