1

我有一个要按顺序处理的记录列表。一个“根”promise 需要被传回以作为另一个父链的一部分添加。

processCategories = function(categories) {
    var deferred = $q.defer();
    var promise = deferred.promise;

    // Process each category in sequence
    angular.forEach(categories, function (data, classIndex) {
        promise = promise.then(doSomethingAndReturnAPromise(categories, data, classIndex));

        if (classIndex === categories.length - 1) {
            // Last category has been reached, resolve this unit of work
            promise.then(function() {
                deferred.resolve(categories);
            });
        }
    });

    // Pass the root promise back to the chain
    return promise;
}

doSomethingAndReturnAPromise = function(categories, data, index) {
    console.log('item : ' + index + ' = started');
    var deferred = $q.defer();

    executeAnAsynchronousCall(function () {
            console.log('item : ' + index + ' = done');
            deferred.resolve(categories);

    }, function(status, text) {
            console.log('item : ' + index + ' = error');
            // Handle error here

    }, data);

    console.log('item : ' + index + ' = returned');
    return deferred.promise;
}

我的异步调用出现了一些错误,因为执行是同时发生的(而不是顺序发生的)。我在上面添加了日志记录并观察到以下内容:

2014-08-08 11:38:02.702 item : 1 = started
2014-08-08 11:38:02.702 item : 1 = returned
2014-08-08 11:38:02.702 item : 2 = started
2014-08-08 11:38:02.703 item : 2 = returned
2014-08-08 11:38:02.703 item : 3 = started
2014-08-08 11:38:02.704 item : 3 = returned
2014-08-08 11:38:02.704 item : 4 = started
2014-08-08 11:38:02.705 item : 4 = returned
2014-08-08 11:38:02.705 item : 5 = started
2014-08-08 11:38:02.706 item : 5 = returned
2014-08-08 11:38:02.707 item : 6 = started
2014-08-08 11:38:02.707 item : 6 = returned
2014-08-08 11:38:02.708 item : 7 = started
2014-08-08 11:38:02.709 item : 7 = returned
2014-08-08 11:38:02.709 item : 8 = started
2014-08-08 11:38:02.710 item : 8 = returned

2014-08-08 11:38:02.716 item : 2 = error
2014-08-08 11:38:02.718 item : 3 = error
2014-08-08 11:38:02.719 item : 4 = error
2014-08-08 11:38:02.720 item : 5 = error
2014-08-08 11:38:02.722 item : 1 = done // (This has finished, the server is now expecting #2)
2014-08-08 11:38:02.723 item : 6 = error
2014-08-08 11:38:02.735 item : 8 = error
2014-08-08 11:38:02.754 item : 7 = error 

我期望.then确保承诺按顺序运行,但每次我运行代码时,它们似乎都被同时触发了。

谁能看到我要去哪里错了?

4

2 回答 2

3

您的第二行是调用该函数,而不是安排稍后调用它

改变:

promise = promise.then(doSomethingAndReturnAPromise(categories, data, classIndex));

至:

promise = promise.then(doSomethingAndReturnAPromise.bind(this,categories, data, index));

或者一个成熟的匿名函数:

promise = promise.then(function(){
    return doSomethingAndReturnAPromise(categories, data, classIndex));
});

附带说明一下,如果您需要使用类别解决的承诺,直接更改返回值而不是将该检查放入 forEach 中会更简单。

processCategories = function(categories) {
    return categories.reduce(function (prev, data, index) {
            return prev.then(function(){
                return doSomethingAndReturnAPromise(categories, data, index));
            });
    }, $q.when()).then(function(){
        return categories;
    });
}
于 2014-08-08T11:35:10.670 回答
0

更改processCategories()为这样的内容:

processCategories = function(categories) {
    var promise, deferred;

    // Process each category in sequence
    angular.forEach(categories, function (data, classIndex) {
      if(promise) {
        promise = promise.then(function() {
           return doSomethingAndReturnAPromise(categories, data, classIndex);
        });
      } else
        promise = doSomethingAndReturnAPromise(categories, data, classIndex);
    });

    if(promise) {
      promise.then(function() {
        return categories;
      });
    } else {
      deferred = $q.defer();
      promise = deferred.promise;
      deferred.resolve(categories);
    }


    // Pass the last promise
    return promise;
}
于 2014-08-08T12:52:12.010 回答