Angular中的链式承诺 [英] Chained promises in Angular

查看:96
本文介绍了Angular中的链式承诺的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个要按顺序处理的记录列表.需要将根"承诺传递回去,以作为另一个父链的一部分添加.

I have a list of records I want to process in sequence. A "root" promise needs to be passed back to be added as part of another parent chain.

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;
}

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

I'm getting some errors from my asynchronous call because the executions are occurring at the same time (and not sequentially). I added the logging above and observed the following:

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确保按顺序运行promise,但是每次运行代码时,它们似乎都被立即解雇了.

I was expecting the .then to ensure the promises are run in sequence, but each time I run the code it appears they are all being fired at once.

有人可以看到我在哪里错吗?

Can anyone see where I'm going wrong here?

推荐答案

您的第二行正在调用该函数,而不是计划在以后调用该函数

Your second line is invoking the function rather than scheduling it to be invoked later

更改:

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会更简单.

As a side note, if you need the promise to resolve with the categories, it would be simpler to change the return value directly rather than put that check in the 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;
    });
}

这篇关于Angular中的链式承诺的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆