Angular JS 및 웹 워커
어떻게 각져?JS는 웹 워커를 사용하여 백그라운드에서 프로세스를 실행합니까?제가 따라야 할 패턴이 있나요?
현재 별도의 웹워커에서 모델을 가지고 있는 서비스를 이용하고 있습니다.이 서비스는 다음과 같은 방법을 구현합니다.
ClientsFacade.calculateDebt(client1); //Just an example..
실장에서는 이 메서드가 데이터와 함께 워커에게 메시지를 보냅니다.이를 통해 다른 스레드에서 수행되고 있다는 사실을 추상화할 수 있습니다.또한 서버 또는 같은 스레드에서 이 액션을 수행하는 서버에 대해 쿼리하는 구현도 제공할 수 있습니다.
javascript를 처음 사용하는데다 다른 플랫폼의 지식을 재활용하고 있기 때문에 이것이 당신이 할 수 있는 것인지, 아니면 제가 사용하고 있는 Angular가 이것을 하는 방법을 제공하고 있는지 궁금합니다.또한 작업자가 명시적으로 컨트롤러에 변경을 푸시해야 하기 때문에 아키텍처가 바뀌게 됩니다.이러한 변경은 컨트롤러의 값을 갱신하고 뷰에 반영됩니다.이러한 변경은 엔지니어링을 오버하는 것입니까?웹 워커가 기억을 공유하지 못하게 함으로써 저를 망치는 것으로부터 보호하는 것은 조금 답답합니다.
웹 워커와의 통신은 메시징 메커니즘을 통해 이루어집니다.이러한 메시지의 대행 수신은 콜백으로 이루어집니다.AngularJS에서는 웹워커를 배치하기 위한 최적의 장소는 당신이 적시했던 서비스 내입니다.이 문제를 해결하는 가장 좋은 방법은 Angular가 놀라울 정도로 잘 작동하는 약속을 사용하는 것입니다.
예를 들어 다음과 같습니다.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;
}
};
});
이제 Hello World 서비스에 액세스하는 외부 엔티티는 다음 구현 세부 사항에 신경 쓸 필요가 없습니다.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);
또, Web 워커의 사양에서는, 데드록이나 라이브 록등의 발생을 방지하기 위해서, 워커와 메인 스레드 콘텍스트는 완전히 분리되어 있습니다.하지만 그것은 또한 당신이 약간의 만지작거림 없이는 당신의 각진 서비스에 접근할 수 없다는 것을 의미한다.워커는 브라우저에서 JavaScript를 실행할 때 글로벌 변수 "document" 등 우리가 기대하는 것(및 각도)이 부족하다.이러한 필수 브라우저 기능을 워커에 "mocking"함으로써 실행할 각도가 정해집니다.
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;
});
}]);
종업원이 결과를 반환할 때까지 대기하기 위해 약속을 사용합니다.
폴링 예제를 사용하는 앵귤러 Web 워커
Angular에서 일하는 사람들을 상대할 때JS에서는 종종 작업자 스크립트가 인라인 상태여야 합니다(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에서 테스트되고 있습니다.
angular plugin 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
'programing' 카테고리의 다른 글
| NSJON Serialization을 통해 JSON에 null 값을 포함하려면 어떻게 해야 합니까? (0) | 2023.04.04 |
|---|---|
| 인터페이스를 사용하여 클래스를 시리얼화하려면 어떻게 해야 합니까? (0) | 2023.04.04 |
| WordPress를 사용하여 제거할 때 테이블을 드롭하는 방법 (0) | 2023.04.04 |
| Bower 의존관계를 최소 버전으로 대체하도록 Grunt를 설정하는 방법 (0) | 2023.04.04 |
| JSON을 로 변환하는 동안 오류가 발생했습니다.asp.net의 넷오브젝트 (0) | 2023.04.04 |