2016-09-02 21 views
0

我需要基於web worker的「回調」來從我的範圍更新一個變量。這些網絡工作者基本上是以特定間隔返回值的時間間隔。如何使用間隔將角度範圍綁定到Web Worker的結果?

這裏是我的worker.js

var timer = false; 
var onmessage = function (e) { 
    var value = e.data[0]; 
    var stock = e.data[1]; 
    var interval = e.data[2]; 

    if (timer) { 
     clearInterval(timer); 
    } 

    timer = setInterval(function() { 
     stock += value; 
     postMessage(stock); 
    }, interval) 
} 

我知道怎麼去使用一個承諾網絡工作者的結果,但是,如我所料,它僅適用於第一個回調。

app.factory('workerServices', ['$q', function ($q) { 
    var worker = new Worker('worker.js'), 
     defer = $q.defer(); 

    worker.onmessage = function (e) { 
     console.log('Result worker:' + e.data); //displayed each "interval" 
     defer.resolve(e.data); 
    } 

    return { 
     increment: function (value, stock, interval) { 
      defer = $q.defer(); 
      worker.postMessage([value, stock, interval]); 
      return defer.promise; 
     } 
    }; 
}]); 

app.controller('mainCtrl', ['$scope', 'workerServices', function ($scope, workerServices) { 
    var value = 1, 
     stock = 0, 
     interval = 300; 

    workServices.increment(val, stock, interval).then(function (newStock) { 
     $scope.stock = newStock; //updated once 

    }); 
}]); 

於是,我就結果綁定到範圍直接看看它是否工作(這是我,因爲我想用工廠爲我的網絡工作者不喜歡)。

而且它沒有工作。我不知道爲什麼,但即使console.log正常工作,我的範圍仍然保持不變。

app.controller('mainCtrl', function ($scope) { 
    var value = 1, 
     stock = 0, 
     interval = 300; 

    var worker = new Worker('worker.js'); 
    worker.postMessage([value, stock, interval]); 
    worker.onmessage = function (e) { 
     console.log(e.data) //properly displayed 
     $scope.result = e.data; // never updated 
    }; 
}); 

我在這裏錯過了什麼?我怎樣才能「連續地」從我的範圍更新一個變量到Web工作者的結果?

+0

在第二種情況下,你可以在'$ scope.result = data'後面嘗試'$ scope()。$ apply()'嗎? – Developer

回答

1

Webworker事件onmessage正在角上下文之外發生,所以角度摘要系統不會有更新綁定的任何想法。在這種情況下,我們需要通過調用$scope.$apply()來明確說出角度來啓動摘要循環。

相反,我會說寧願使用$timeout這將是最安全的方法來應用消化週期。因爲有時直接運行$apply方法可能會導致digest cycle is in already progress錯誤與當前運行週期衝突。

worker.onmessage = function (e) { 
    console.log(e.data) //properly displayed 
    $timeout(function(){ 
     $scope.result = e.data; // never updated 
    }); 
}; 
1

在第二種情況下,你可以嘗試$scope.result = data$scope().$apply()

而在你的第一個案例中,AFAIK你無法解決相同的承諾兩次,這就是你沒有得到預期結果的原因。我建議你去訂閱者監聽模式來實現這個$ broadcast/$ emit方法。這tutorial會給你一個良好的開端。

相關問題