Javascript AngularJS承诺$q.all和信号员

Javascript AngularJS承诺$q.all和信号员,javascript,angularjs,signalr,promise,q,Javascript,Angularjs,Signalr,Promise,Q,我已经检查了许多关于承诺的答案,但是我的代码无法正常工作(也许我在其他地方做了一些非常错误的事情) 一般来说,我正在使用AngularJS和Signal开发小型测试应用程序。我的信号机服务如下所示: (function () { 'use strict'; var serviceId = 'signalRSvc'; angular.module('app').service(serviceId, ['$rootScope', signalrcontext]); function signal

我已经检查了许多关于承诺的答案,但是我的代码无法正常工作(也许我在其他地方做了一些非常错误的事情)

一般来说,我正在使用AngularJS和Signal开发小型测试应用程序。我的信号机服务如下所示:

(function () {
'use strict';

var serviceId = 'signalRSvc';
angular.module('app').service(serviceId, ['$rootScope', signalrcontext]);

function signalrcontext( $rootScope) {
    var performanceHub = null;
    var connection = null;        

    var service = {
        initialize: initialize,
        getPerformanceCounters: getPerformanceCounters,
        getAllValues: getAllValues
    };

    return service;

    function initialize() {
        connection = $.connection;

        performanceHub = connection.webServicePerformanceHub;
        connection.hub.logging = true;

        performanceHub.client.updatePerformanceData = function(performanceData) {
            $rootScope.$emit("updatePerformanceData", performanceData);
        };

        return connection.hub.start();
    };

    function getPerformanceCounters() {
        return performanceHub.server.getPerformanceCounters();
    };

    function getAllValues(id) {
        return performanceHub.server.getAllValues(id);
    };
}
})();
我试图做的是初始化SignalR,然后执行getPerformanceCounters()方法,该方法将下载要呈现的计数器列表(作为对象数组返回),然后针对每个我想要获取数据的计数器,问题开始了。根据MS文件,信号代理方法正在返回承诺。我已经写了这段代码,但我不知道为什么它不能在步骤getAllValues上工作(根据这个答案,它应该可以工作)

在我的理解中,last-then应该在对signalRSvc.getAllValues的所有“调用”完成时执行,并且resultData应该包含从这些承诺返回的对象数组。相反,我得到的是一些甚至不是数组的垃圾

令人惊讶的是(当然对我来说)当我做这样的事情时

    function getAllValues(configurations) {
        var promises = new Array();

        angular.forEach(configurations, function(configuration) {
            promises.push(signalRSvc.getAllValues(configuration.Id));
        });

        return $q.all(promises).then(function(resultData) {  
           //here result data is fine!!
        });
    }
在嵌套中,然后结果数据就可以了(当然,解析承诺的顺序是混乱的)

因为我没有主意了,所以提前谢谢你的帮助

我的朋友为AngularJS写了一个很棒的信号器包装器。你可以从GitHub下载, 这个包装器还使用$q承诺来获得结果

示例:

hubFactory.getHub("myHub").run("myMethod", param_1, param_2, .... param_n).then ( function(responseData) {} )

可以将initsignal()更改为以下内容吗

function initSignalR() {
    return signalRSvc.initialize().then(function() {                
        return signalRSvc.getPerformanceCounters();
    }).then(function(configurations) {
        log('performance counters configuration downloaded');
        getAllValues(configurations).then(function (resultData) {
            vm.resultData = resultData;
        });
    });
}

我知道这并不漂亮,但显然jQuery的then方法显然无法正确地打开$q承诺,即使$q承诺有自己的then方法。

问题似乎与SingalR返回的承诺有关(我团队的同事发现了这一点)。SignalR返回的jQuery承诺在所有情况下都与AngularJS承诺“不兼容”。解决方案是使用$q包装来自signalR代理的方法。现在一切正常

固定代码(仍包含一些其他与信号器相关的问题)

以前不起作用的承诺链现在可以正常工作

function initSignalR() {
    return signalRSvc.initialize().then(function () {
        return signalRSvc.getPerformanceCounters();
    }).then(function (configurations) {
        chartConfigurations = configurations;                
        return getAllValues(configurations);
    }).then(function (chartData) {
        angular.forEach(chartData, function(value, key) {
        chartConfigurations[key].chartData = convertToChartDataset(value);
        chartConfigurations[key].options = {
            animation: false
            };
        });

        vm.configurations = chartConfigurations;
    });
}

function getAllValues(configurations) {
    var promises = [];

    $.each(configurations, function (index, value) {
        promises.push(signalRSvc.getAllValues(value.Id));
    })

    return $q.all(promises);
}

嗨,Alex,我会检查这个包装器,尽管我认为问题与承诺本身有关,而不是与信号器有关。我有推杆参考信号,以防它可能是问题的根源。
.....

return service;

function initialize() {
    connection = $.connection;

    performanceHub = connection.webServicePerformanceHub;
    connection.hub.logging = true;

    performanceHub.client.updatePerformanceData = function(performanceData) {
        $rootScope.$emit("updatePerformanceData", performanceData);
    };

    return $q.when(connection.hub.start();
};

function getPerformanceCounters() {
    return $q.when(performanceHub.server.getPerformanceCounters());
};

function getAllValues(id) {
    return $q.when(performanceHub.server.getAllValues(id));
};
.....
function initSignalR() {
    return signalRSvc.initialize().then(function () {
        return signalRSvc.getPerformanceCounters();
    }).then(function (configurations) {
        chartConfigurations = configurations;                
        return getAllValues(configurations);
    }).then(function (chartData) {
        angular.forEach(chartData, function(value, key) {
        chartConfigurations[key].chartData = convertToChartDataset(value);
        chartConfigurations[key].options = {
            animation: false
            };
        });

        vm.configurations = chartConfigurations;
    });
}

function getAllValues(configurations) {
    var promises = [];

    $.each(configurations, function (index, value) {
        promises.push(signalRSvc.getAllValues(value.Id));
    })

    return $q.all(promises);
}