2016-09-02 1 views
0

ウェブワーカーの「コールバック」に基づいて、自分のスコープから変数を更新する必要があります。これらのWebワーカーは、基本的に特定の間隔で値を返す間隔です。ここで区間を使用しているWebワーカーの結果に角度範囲をバインドする方法はありますか?

は、私はそれが唯一の最初のコールバックのために働き、私は予想通り、約束を使用して、Webワーカーから結果を取得する方法を知っているが、私の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

2番目のケースでは、 '$ scope.result = data'の後に' $ scope()。$ apply() 'を試してみることができますか? – Developer

答えて

1

Webworkerイベントonmessageは角度の外で起こっているため、角度ダイジェストシステムではバインディングを更新するようには考えていません。このような場合、$scope.$apply()を呼び出すことによって、ダイジェストサイクルを手動で開始するために角度を明示的に言う必要があります。

むしろ、ダイジェストサイクルを適用する最も安全な方法である$timeoutを使用するといいでしょう。 $applyメソッドを直接実行すると、現在実行中のサイクルと競合してdigest cycle is in already progressエラーが発生する可能性があるためです。第2のケースで

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は同じ約束を2度解決することはできません。なぜなら、期待した結果が得られない理由です。この$ broadcast/$ emitメソッドを実現するために、サブスクライバ・リスナー・パターンを使用することをお勧めします。このtutorialはあなたに良いスタートを与えるでしょう。

関連する問題