2014-01-14 112 views
2

我檢查了有關承諾的答案數,但我不能讓我的代碼工作(也許是我在做什麼可怕的錯誤在其他地方)

總的來說,我」使用AngularJS和SignalR開發小型測試應用程序。我有signalR服務,看起來像這樣:

(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文檔,SignalR代理方法正在返回promise。我已經寫了這個代碼,但我不知道它爲什麼不一步getAllValues工作(按照這個答案AngularJS Promises, $q, defer它應該工作)

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

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

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

     return $q.all(promises); 
    } 

在我的理解,最後再當所有的「呼籲」,以應執行signalRSvc.getAllValues已完成,resultData應包含從這些promise返回的對象數組。而不是這個,我得到一些甚至不是數組的垃圾。

令人驚訝的(對我來說當然)當我這樣做

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!! 
     }); 
    } 
嵌套然後導致數據

是好的(當然解決承諾的順序亂了)。

感謝您提前幫助,因爲我沒有想法。

回答

2

看起來問題與SingalR返回的承諾有關(我的團隊的同事發現此問題)。 SignalR返回的jQuery承諾在所有情況下都與AngularJS承諾不兼容。解決方案是將來自signalR代理的方法用$ q.When包裝。現在一切正常。

固定碼(其中仍包含一些其他SignalR相關的問題),這是以前沒有工作

..... 

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

我的朋友Yan Yankowski寫了一個很棒的SignalR AngularJS的包裝。你可以download它從GitHub, 這個包裝也使用$ q承諾獲得結果。

例子:

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

嗨亞歷克斯,我會檢查這個包裝,儘管我認爲這個問題與承諾本身而不是信號相關。我推杆提及signalR以防萬一它可能是問題的根源。 – Midi

0

可你只需要改變initSignalR()以下內容?

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的則方法顯然不正確解開$ Q承諾即使$ Q承諾有自己則方法。