如何让for循环等待每个回调完成

时间:2015-07-27 22:00:52

标签: angularjs

我正在调用一个服务来获取一组ID,然后循环遍历每个ID并将其他服务调用到各自的数据。控制台显示 for循环中的getBookings服务未按顺序处理。

   service.getStoreIDs(function (data1) {
        var scheduledBookings = [];

        console.log('StoreIDs = ' + data1.length); // There are only 3 in my test data

        for (var storeID in data1) {
            var s = data1[storeID];
            var storeno = s['Storeno'];

            service.getBookings(storeno, "", function (data2) {

                if (data2.length == 0) {
                    scheduledBookings.push({ Storeno: storeno, Id: 0 });
                }
                else {
                    console.log('[BuildMFB] Storeno ' + storeno + ' = ' + data2.length + ' bookings')
                    for (var book in data2) {
                        var b = data2[book];

                        prevStoreno = storeno;

                        scheduledBookings.push({
                            Storeno: (prevStoreno == storeno ? "" : storeno),
                            Id: b.Id,
                            BookedBy: b.BookedBy,
                            Description: b.Description,
                            StartDate: b.StartDate,
                            EndDate: b.EndDate,
                        });
                    }
                    prevStoreno = storeno;
                }
            });
        }
        $scope.currentBookings = scheduledBookings;
    });

所有预订都被分配到商店144,正如您从下面的控制台消息中看到的那样,因为它只有1个预订,所以这是正确的。

我只能认为这是一个异步处理问题(?)。

控制台消息(BuildMFB是当前函数):

[BuildMFB] StoreIDs = 3
[BuildMFB] storeID: 101
[BuildMFB] storeID: 131
[BuildMFB] storeID: 144
[getBookings] Storeno 101 has 5 bookings
[BuildMFB] Storeno 144 = 5 bookings
[BuildMFB] Added 253 for 144
[BuildMFB] Added 151 for 144
[BuildMFB] Added 215 for 144
[BuildMFB] Added 217 for 144
[BuildMFB] Added 208 for 144
[BuildMBF] currentBookings = 5
[getBookings] Storeno 131 has 2 bookings
[BuildMFB] Storeno 144 = 2 bookings
[BuildMFB] Added 227 for 144
[BuildMFB] Added 226 for 144
[BuildMBF] currentBookings = 7
[getBookings] Storeno 144 has 1 bookings
[BuildMFB] Storeno 144 = 1 bookings
[BuildMFB] Added 238 for 144
[BuildMBF] currentBookings = 8

使用getBookings方法更新:

var getBookings = function (storeno, userid, callback) {
    var filterString = "";

    if (storeno != "0" && userid != "") {
        filterString = "?$filter=(Title eq '" + storeno + "') and (Status eq 'Booked') and (BookedBy eq '" + userid + "')&$orderby=Title asc";
    }
    else if (storeno != "0") {
        filterString = "?$filter=(Title eq '" + storeno + "') and (Status eq 'Booked')&$orderby=Title asc";
    }
    else if (userid != "") {
        filterString = "?$filter=(Status eq 'Booked') and (BookedBy eq '" + userid + "')&$orderby=Title asc";
    }
    else {
        filterString = "?$filter=(Status eq 'Booked')&$orderby=Title asc";
    }

    $http({
        method: 'GET',
        url: "/_api/web/lists/GetByTitle('Bookings')/Items" + filterString,
        headers: {
            'Accept': 'application/json; odata=verbose'
        },
    }).success(function (d) {
        var bookings = [];

        $(d.d.results).each(function (i, e) {
            bookings.push({
                Id: e['Id'],
                Storeno: e['Title'],
                BookedBy: e['BookedBy'],
                Description: e['Description'],
                StartDate: e['StartDate'],
                EndDate: e['EndDate'],
            });
        });

        callback(bookings);

    }).error(function (er) {
        alert("[getBookings] http error : " + er);
    });
};

1 个答案:

答案 0 :(得分:1)

虽然您已在for循环中定义了局部变量,但它们的定义实际上将被提升到函数的开头,然后在任何异步任务完成之前,每次迭代都会更新这些变量。一个简单的解决方案是使用foreach实用程序函数,如jQuery的$.each或下划线的_.each,它为每次迭代调用一个函数。

编辑:抱歉,更新了键值而不是数组。

...
$.each(data1, function (storeID, s) {
    var storeno = s['Storeno'];
    ...
});
...