Promise.all()返回一个意外的值

时间:2017-08-16 20:46:28

标签: javascript angularjs angular-promise es6-promise

我真的很困惑我的代码,这是一个angularjs服务。我试图使用Promise.all来连接作为服务一部分的两个promise,并将结果发送给我的控制器。 问题是Promise.all返回的对象由两个相同的数组组成。 我的代码在这里,为了更清楚:

batchModule.service('BatchService', ['$http', '$q', '$log', 'MessageboxService', function ($http, $q, $log, MessageboxService) {

let deferred = $q.defer();

this.loadAll = () => {

    promise1 = () => {
        $http.get(_restApiPath + "/batch/?processtype=IMPORT_CUSTOMER")
        // loadLastFiveBatch('IMPORT_CUSTOMER')
            .then(function (response) {
                deferred.resolve(response.data);
                // datas.push(response1);
                // console.log(datas);
            }, function (error) {
                deferred.reject(error);
                $log.error(error);
            });
        return deferred.promise;
    };

    promise2 = () => {
        $http.get(_restApiPath + "/batch/?processtype=IMPORT_LAB_MARGIN")
        // loadLastFiveBatch('IMPORT_LAB_MARGIN')
            .then(function (response) {
                deferred.resolve(response.data);
                // datas.push(response2);
                // console.log(datas);
            }, function (error) {
                deferred.reject(error);
                $log.error(error);
            });
        return deferred.promise;
    };

    Promise.all([promise1(), promise2()])
    .then(values => {
        console.log(values);
    });

};
}]);

当PromORT.all的第二个参数恰好是IMPORT_MARGIN请求返回的promise时,console.log(values)返回由IMPORT_CUSTOMER请求返回的2个相等数组组成的对象。 我今天已经工作了几个小时,但我找不到任何解决方案。 我希望我很清楚,我的英语不是很好。 谢谢你的答案:-)

2 个答案:

答案 0 :(得分:1)

你的承诺实际上都会返回相同的$q.defer();承诺。所以你需要删除延迟的反模式(使用$q.defer()而不是return $http.get(..);),问题应该解决自己。

所以将代码更改为:

batchModule.service('BatchService', ['$http', '$q', '$log', 'MessageboxService', function ($http, $q, $log, MessageboxService) {

    this.loadAll = () => {

        promise1 = () => {
            return $http.get(_restApiPath + "/batch/?processtype=IMPORT_CUSTOMER")
                .then(response => response.data, error => {
                    $log.error(error);
                    return $q.reject(error);
                });
        };

        promise2 = () => {
            return $http.get(_restApiPath + "/batch/?processtype=IMPORT_MARGIN")
                .then(response => response.data, error => {
                    $log.error(error);
                    return $q.reject(error);
                });
        };

        $q.all([promise1, promise2])
        .then(values => {
            console.log(values);
        });
    };
}]);

答案 1 :(得分:1)

由于您使用单个延期的所有承诺而导致的问题。因此,单个引用得到解决,它将解决您的promise调用的进一步实例。因此,请为每个请求使用不同的延迟。我仍然不喜欢使用deferred anti-pattern。而是使用$http.get方法返回承诺中的构建。

此外,在功能结束时您有Promise.all,这不会运行角度摘要周期。最终,如果您要更新此函数的任何绑定,则不会更新UI上的绑定。考虑使用$q.all

进行操作
this.loadAll = () => {

    promise1 = () => {
        return $http.get(_restApiPath + "/batch/?processtype=IMPORT_CUSTOMER")
            .then(function (response) {
                return response.data;
            }, function (error) {
                $log.error(error);
                return $q.reject(error);
            }
        );
    };

    promise2 = () => {
        $http.get(_restApiPath + "/batch/?processtype=IMPORT_LAB_MARGIN")
        // loadLastFiveBatch('IMPORT_LAB_MARGIN')
            .then(function (response) {
                return response.data;
            }, function (error) {
                $log.error(error);
                return $q.reject(error);
            }
        );
    };
    //return is needed if any function is trying to chain `loadAll` function.
    return $q.all([promise1(), promise2()])
    .then(values => {
        console.log("promise1", values[0]);
        console.log("promise2", values[1]);
    });

};