通过递归循环请求同步ajax

时间:2016-03-25 21:40:25

标签: javascript ajax

我正在尝试通过向发送邮件的脚本发出ajax请求,向许多接收者发送简报邮件。为了确保先前的请求完成(以便未达到浏览器的最大并发请求数),我使用递归循环函数。

这个问题在不同的版本中已被问过几次,但我找不到任何可以帮助我的答案。

我尝试了什么:

var receiverarray = <?php echo json_encode($receiverarray); ?>; // All data is correctly received from PHP
var nrofreceivers = '<?php echo count($receiverarray); ?>';
nrofreceivers = parseInt(nrofreceivers);
function sendmailreceivers(receiverarray, callback) {
    try  {
        var a = 0;
        recur_loop(a);
        function recur_loop(i) {
            var num = i;
            if (num < nrofreceivers) {
                var count = num + 1;
                var percentage = (count / receiverarray.length) * 100;
                percentage = Math.round(percentage);
                var loadingtext = String(count) + " van " + String(nrofreceivers) + " (" + String(percentage) + "%)";
                $('#loadingtext').html(loadingtext);
                var thisreceiverarray = receiverarray[num];
                $.ajax({
                    type: "POST",
                    url: "https://www.domain.com/scripts/sendmail.php", // Script works fine
                    data: {
                        'from_mail': '<?php echo $webmastermailaddress; ?>',
                        'from_name': 'Webmaster name',
                        'to_mail': thisreceiverarray.email,
                        'to_name': thisreceiverarray.name,
                        'reply_name': 'Business name',
                        'reply_mail': 'Business mail address',
                        'diff_mailer': '',
                        'mail_content': '<HTML>The html mail content</HTML>',
                        'mail_subject': '<?php echo $subject; ?>'
                    },
                    success: function(){
                        recur_loop(count);
                    },
                    error: function() {
                        throw "Error!";
                    }
                });
            }
        };
        callback();
    }
    catch(err) {
        throw "Error!";
    }
}

这适用于前3个邮件地址。然后由于未知原因,该函数完成,并且回调确保执行下一个函数(我将用户重定向到感谢页面)。

所以看起来每封邮件都已发送,因为该功能完成且没有错误,但实际上只发送了3封邮件。

我已经花了很多天寻找答案并试图解决它,但没有运气。控制台中没有错误?

为什么功能过早完成?

1 个答案:

答案 0 :(得分:1)

我尝试改进你的代码,它仍然不完美:

var receiverarray = <?php echo json_encode($receiverarray); ?>;

function sendmailreceivers(callback) {
    try {
        recur_loop(0);
        function recur_loop(i) {
            if (i === receiverarray.length) {
              return callback();
            }
            var percentage = Math.round((i / receiverarray.length) * 100);
            var loadingtext = i + " van " + receiverarray.length + " (" + percentage + "%)";
            $('#loadingtext').text(loadingtext);
            var thisreceiverarray = receiverarray[i];
            $.ajax({
                type: "POST",
                url: "https://www.domain.com/scripts/sendmail.php", // Script works fine
                data: {
                    'from_mail': '<?php echo $webmastermailaddress; ?>',
                    'from_name': 'Webmaster name',
                    'to_mail': thisreceiverarray.email,
                    'to_name': thisreceiverarray.name,
                    'reply_name': 'Business name',
                    'reply_mail': 'Business mail address',
                    'diff_mailer': '',
                    'mail_content': '<HTML>The html mail content</HTML>',
                    'mail_subject': '<?php echo $subject; ?>'
                },
                success: function(){
                    recur_loop(i + 1);
                },
                error: function(err) {
                    callback(err);
                }
            });
        }
    } catch(err) {
        callback(err);
    }
}

sendmailreceivers(function(err) {
    if (err) {
        console.error(err.stack);
        alert('Error!');
    } else {
        alert('Done');
    }
});

一些评论:

  • 您在第一次请求完成之前致电callback
  • try { ... } catch(err) { throw "Error"; }会吞下一条有意义的错误消息并将其替换为“错误” - 不是很有用。
  • 如果.text(str)包含的文字不是html代码,请更好地使用.html代替str
  • 通常最好添加err作为回调函数的第一个参数,以返回可能的错误。
  • String(val)parseInt(val, 10)仅用于转换值类型
  • 除了较旧的PHP版本之外,您无需先将所有内容存储在变量中,然后才能使用它。例如,将函数的返回值作为参数传递是完全正确的。