AngularJS와 웹 워커
angularJS는 어떻게 웹 워커를 사용하여 백그라운드에서 프로세스를 실행할 수 있습니까? 이 작업에 따라야 할 패턴이 있습니까?
현재는 별도의 웹 워커에서 모델이있는 서비스를 사용하고 있습니다. 이 서비스는 다음과 같은 메소드를 구현합니다.
ClientsFacade.calculateDebt(client1); //Just an example..
구현에서이 메서드는 데이터와 함께 작업자에게 메시지를 보냅니다. 이를 통해 별도의 스레드에서 수행되고 있다는 사실을 추상화 할 수 있으며 서버 또는 동일한 스레드에서이 작업을 수행하는 서버에 대해 쿼리하는 구현도 제공 할 수 있습니다.
나는 자바 스크립트를 처음 접하고 다른 플랫폼에서 얻은 지식을 재활용하고 있기 때문에 이것이 당신이 할 일인지 아니면 내가 사용하고있는 Angular가 일종의 방법을 제공하는지 궁금합니다. 또한 작업자가 변경 사항을 컨트롤러에 명시 적으로 푸시 한 다음 해당 값을 업데이트 한 다음 뷰에 반영되어야하므로 내 아키텍처가 변경됩니다. 웹 작업자가 메모리 공유 등을 허용하지 않음으로써 나를 망치지 않도록 "보호"하는 것은 약간 실망 스럽습니다.
웹 작업자와의 통신은 메시징 메커니즘을 통해 이루어집니다. 이러한 메시지를 가로채는 것은 콜백에서 발생합니다. AngularJS에서 웹 워커를 배치하기에 가장 좋은 위치는 귀하가 적법하게 언급 한대로 서비스에 있습니다. 이를 처리하는 가장 좋은 방법은 Angular가 놀랍게 작동하는 promise를 사용하는 것입니다.
다음은 a의 예입니다 webworker
.service
var app = angular.module("myApp",[]);
app.factory("HelloWorldService",['$q',function($q){
var worker = new Worker('doWork.js');
var defer = $q.defer();
worker.addEventListener('message', function(e) {
console.log('Worker said: ', e.data);
defer.resolve(e.data);
}, false);
return {
doWork : function(myData){
defer = $q.defer();
worker.postMessage(myData); // Send data to our worker.
return defer.promise;
}
};
});
이제 외부 무엇이든의 구현 세부 사항에 대해 걱정하지 안녕하세요 서비스의 필요성을 액세스 개체는 HelloWorldService
- HelloWorldService
아마 통해 데이터를 처리 할 수있는 web worker
이상, http
또는 바로 처리 할.
이것이 의미가 있기를 바랍니다.
매우 흥미로운 질문입니다! 나는 웹 작업자 사양이 약간 어색하다고 생각합니다 (아마도 좋은 이유가 있지만 여전히 어색합니다). 작업자 코드를 별도의 파일에 보관해야하기 때문에 서비스의 의도를 읽기 어렵고 각 애플리케이션 코드의 정적 파일 URL에 종속성이 도입됩니다. 이 문제는 JavaScript 문자열에 대한 URL을 만드는 데 사용할 수있는 URL.createObjectUrl ()을 사용하여 완화 할 수 있습니다. 이를 통해 작업자를 생성하는 동일한 파일에서 작업자 코드를 지정할 수 있습니다.
var blobURL = URL.createObjectURL(new Blob([
"var i = 0;//web worker body"
], { type: 'application/javascript' }));
var worker = new Worker(blobURL);
웹 작업자 사양은 교착 상태 및 라이브 록 등이 발생할 수있는 상황을 방지하기 위해 작업자 및 주 스레드 컨텍스트를 완전히 분리합니다. 그러나 그것은 또한 약간의 조작 없이는 작업자의 각도 서비스에 액세스 할 수 없음을 의미합니다. 작업자는 전역 변수 "document"등과 같이 브라우저에서 JavaScript를 실행할 때 기대하는 것 (및 각도)이 부족합니다. 작업자에서 이러한 필수 브라우저 기능을 "조롱"함으로써 각도를 실행할 수 있습니다.
var window = self;
self.history = {};
var document = {
readyState: 'complete',
cookie: '',
querySelector: function () {},
createElement: function () {
return {
pathname: '',
setAttribute: function () {}
};
}
};
일부 기능은 분명히 작동하지 않고 DOM에 바인딩합니다. 그러나 주입 프레임 워크와 예를 들어 $ http 서비스는 잘 작동합니다. 아마도 우리가 워커에서 원하는 것입니다. 이것으로 얻은 것은 작업자에서 표준 각도 서비스를 실행할 수 있다는 것입니다. 따라서 다른 각도 종속성과 마찬가지로 작업자에서 사용되는 서비스를 단위 테스트 할 수 있습니다.
나는 좀 더 이것에 대해 부연 게시물 만든 여기를 와 아이디어가 위에서 설명한 구현하는 서비스를 생성하는 github의의 REPO 만들어 여기를
Angular 에서 완전히 작동하는 웹 작업자 예제를 찾았 습니다.
webworker.controller('webWorkerCtrl', ['$scope', '$q', function($scope, $q) {
$scope.workerReplyUI;
$scope.callWebWorker = function() {
var worker = new Worker('worker.js');
var defer = $q.defer();
worker.onmessage = function(e) {
defer.resolve(e.data);
worker.terminate();
};
worker.postMessage("http://jsonplaceholder.typicode.com/users");
return defer.promise;
}
$scope.callWebWorker().then(function(workerReply) {
$scope.workerReplyUI = workerReply;
});
}]);
작업자가 결과를 반환 할 때까지 기다리는 약속을 사용합니다.
폴링 예제가있는 Angular Web Worker
AngularJS에서 작업자를 다룰 때 작업자 스크립트가 인라인 (gulp / grunt와 같은 일부 빌드 도구를 사용하는 경우)이어야하는 경우가 많으며 다음 접근 방식을 사용하여이를 달성 할 수 있습니다.
아래 예는 작업자를 사용하여 서버에 폴링을 수행하는 방법도 보여줍니다.
먼저 작업자 팩토리를 만듭니다.
module.factory("myWorker", function($q) {
var worker = undefined;
return {
startWork: function(postData) {
var defer = $q.defer();
if (worker) {
worker.terminate();
}
// function to be your worker
function workerFunction() {
var self = this;
self.onmessage = function(event) {
var timeoutPromise = undefined;
var dataUrl = event.data.dataUrl;
var pollingInterval = event.data.pollingInterval;
if (dataUrl) {
if (timeoutPromise) {
setTimeout.cancel(timeoutPromise); // cancelling previous promises
}
console.log('Notifications - Data URL: ' + dataUrl);
//get Notification count
var delay = 5000; // poller 5sec delay
(function pollerFunc() {
timeoutPromise = setTimeout(function() {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var response = JSON.parse(xmlhttp.responseText);
self.postMessage(response.id);
pollerFunc();
}
};
xmlhttp.open('GET', dataUrl, true);
xmlhttp.send();
}, delay);
})();
}
}
}
// end worker function
var dataObj = '(' + workerFunction + ')();'; // here is the trick to convert the above fucntion to string
var blob = new Blob([dataObj.replace('"use strict";', '')]); // firefox adds user strict to any function which was blocking might block worker execution so knock it off
var blobURL = (window.URL ? URL : webkitURL).createObjectURL(blob, {
type: 'application/javascript; charset=utf-8'
});
worker = new Worker(blobURL);
worker.onmessage = function(e) {
console.log('Worker said: ', e.data);
defer.notify(e.data);
};
worker.postMessage(postData); // Send data to our worker.
return defer.promise;
},
stopWork: function() {
if (worker) {
worker.terminate();
}
}
}
});
다음으로 컨트롤러에서 작업자 공장을 호출합니다.
var inputToWorker = {
dataUrl: "http://jsonplaceholder.typicode.com/posts/1", // url to poll
pollingInterval: 5 // interval
};
myWorker.startWork(inputToWorker).then(function(response) {
// complete
}, function(error) {
// error
}, function(response) {
// notify (here you receive intermittent responses from worker)
console.log("Notification worker RESPONSE: " + response);
});
myWorker.stopWork();
언제든지 전화 하여 컨트롤러에서 작업자를 종료 할 수 있습니다 !
이것은 IE11 + 및 FF 및 Chrome에서 테스트되었습니다.
각도 플러그인 https://github.com/vkiryukhin/ng-vkthread를 살펴볼 수도 있습니다.
별도의 스레드에서 함수를 실행할 수 있습니다. 기본 사용법 :
/* function to execute in a thread */
function foo(n, m){
return n + m;
}
/* create an object, which you pass to vkThread as an argument*/
var param = {
fn: foo // <-- function to execute
args: [1, 2] // <-- arguments for this function
};
/* run thread */
vkThread.exec(param).then(
function (data) {
console.log(data); // <-- thread returns 3
}
);
예제 및 API 문서 : http://www.eslinstructor.net/ng-vkthread/demo/
-바딤
참고 URL : https://stackoverflow.com/questions/16713925/angularjs-and-web-workers
'Nice programing' 카테고리의 다른 글
쉘 스크립트에서 상수 변수를 어떻게 선언합니까? (0) | 2020.10.29 |
---|---|
자바 스크립트의 다른 함수 내에서 함수 정의 (0) | 2020.10.29 |
명명 된 문자형 벡터를 data.frame으로 변환 (0) | 2020.10.29 |
Node.js http get 요청에서 데이터를 가져 오는 방법 (0) | 2020.10.29 |
0으로 채워진 팬더 데이터 프레임 만들기 (0) | 2020.10.29 |