jQuery + .each()+ .post()...同步运行吗?

时间:2018-10-08 02:44:05

标签: jquery

我有一个HTML表。该表有几行。我正在运行的jQuery代码将扫描表,并为每一行运行POST请求。下面是我正在使用的代码...

首先,我们设置表格,并从中获取一些数据:

$target = this.$target;

var process = true,
    eventID = $target.data('event'),
    address = $target.data('href');

然后我用.each()遍历所有行

$target.find('.row').each(function()
{
    var $fa = $(this).find('.fa');

    if (process)
    {
        var input = {
            'eventID': eventID,
            'userID': $(this).data('user'),
            'seed': $(this).data('seed'),
        };

        $.post(address, input, function(data)
        {
            $fa.addClass('fa-check-circle-o');
        });
    }
    else
    {
        $fa.addClass('fa-exclamation-triangle');
    }
});

您可以从上面的代码中看到,对于每一行,我都会做几件事:

  • 找到嵌套的.fa分类元素
  • 检查process是否为真
  • 收集几条数据
  • 将数据发布到address

帖子完成后,会在.fa元素上添加fa-check-circle-o标记。

我遇到的问题是所有.each()函数都同时运行,而不是一个接一个地运行。在前进到下一行之前,如何让它等待完成每一行?

我还希望它在发生故障时在元素上添加一个fa-惊叹号三角形标记,并将process标记为false,以便跳过以后的所有行...但是我不知道如何捕捉帖子的失败。

3 个答案:

答案 0 :(得分:3)

您可以简单地使要迭代的元素组成数组,然后在ajax回调中连续调用它们。您可以在此处使用Promise interface来根据请求的成功,失败或完成情况触发操作:

var rows;
$(".button").on('click', function() {
    rows = $('.rows').toArray();
    var row = rows.shift();
    doAjax(row);
});
function doAjax(row) {
    $.post('ajax.php')
        .done(function() {
            // this runs on success
        })
        .fail(function() {
            // this runs on ajax failure
        })
        .always(function() {
            // this always runs
            // call next element in your array now...
            if (rows.length) {
                var row = rows.shift();
                doAjax(row);
            }
        });

}

这是一个有效的示例:http://so-ajax-each.dev.zuma-design.com/

答案 1 :(得分:0)

确保您正在使用ECMA6。我不确定ECMA5中是否也有类似的功能。

<form class="login-form" action="<?=base_url()?>Login_controller/login_submit" method="post">
<div class="wrap-input100 validate-input" data-validate="Valid email is: a@b.c">
    <input class="input100" type="text" name="Username">
    <span class="focus-input100" data-placeholder="Email"></span>
</div>

<div class="wrap-input100 validate-input" data-validate="Enter password">
    <span class="btn-show-pass">
        <i class="zmdi zmdi-eye"></i>
    </span>
    <input class="input100" type="password" name="Password">
    <span class="focus-input100" data-placeholder="Password"></span>
</div>

<div class="container-login100-form-btn">
    <div class="wrap-login100-form-btn">
        <div class="login100-form-bgbtn" ></div>
        <input type="submit" class="login100-form-btn" value="Login">
    </div>
</div>
</form>

答案 2 :(得分:0)

在使用jQuery AJAX时尝试将async选项作为false传递(我稍微修改了您的格式,因为这很烦我):

$target.find('.row').each(function() {
    var $fa = $(this).find('.fa');

    if (process) {
        var input = {
            'eventID': eventID,
            'userID': $(this).data('user'),
            'seed': $(this).data('seed'),
        };

        $.ajax({
            type: 'POST',
            url: address,
            data: input,
            async: false,
            success: function(data) {
                $fa.addClass('fa-check-circle-o');
            }
        });
    } else {
        $fa.addClass('fa-exclamation-triangle');
    }
});