07.02.2017, 17:09
|
Аспирант
|
|
Регистрация: 02.11.2016
Сообщений: 65
|
|
Как в worker-е выполнить SQL-запрос?
Реализовываю работу с воркером через сервисы ('ng-vkThread','ngWebworker'), в данном примере - 'ngWebworker', но ошибку получаю одну и тужу: ReferenceError: $http is not defined
Помогите, в с чем связана проблема?
app.js
var app = angular.module('contactList', ['lumx','ngSanitize', 'ngCsv', 'ng-vkThread','ngWebworker']);
app.controller('ReadFileController', ['$scope','$http','vkThread','Webworker', function ($scope, $http, vkThread, Webworker) {
var foo = function (content) {
$http.post('/anguler-tasks-contacts/addContactData.php',{last_name:1, name:2, patronymic_name:3, address:4, telephone:5, url:6, description:7, completed:'false'}).then(function(response) {
$scope.contactslist.push({
id: response.data[0].id,
last_name: response.data[0].last_name,
name: response.data[0].name,
patronymic_name: response.data[0].patronymic_name,
address: response.data[0].address,
telephone: response.data[0].telephone,
url: response.data[0].url,
description: response.data[0].description,
completed: response.data[0].completed
});
});
return 1;
}
$scope.readContent = function($fileContent){
$scope.content = $fileContent;
var myWorker2 = Webworker.create(foo);
myWorker2.run($scope.content).then(function(result) {
console.log(result);
});
};
}]);
|
|
07.02.2017, 18:31
|
|
Профессор
|
|
Регистрация: 18.05.2011
Сообщений: 1,207
|
|
okuznetsov1,
Твой вебворкер запускается в другом потоке. То есть контекст воркера и ангуляр приложения полностью изолированы поэтому у тебя нет доступа к сервису $http.
Вот готовое решение https://github.com/FredrikSandell/angular-workers
Последний раз редактировалось destus, 07.02.2017 в 18:35.
|
|
08.02.2017, 17:52
|
Аспирант
|
|
Регистрация: 02.11.2016
Сообщений: 65
|
|
Сообщение от destus
|
okuznetsov1,
Твой вебворкер запускается в другом потоке. То есть контекст воркера и ангуляр приложения полностью изолированы поэтому у тебя нет доступа к сервису $http.
Вот готовое решение https://github.com/FredrikSandell/angular-workers
|
Реализовал по вашему решению, вроде бы получилось. Можете подсказать правильно ли сделал? Предполагаю, что есть ошибки, хотя код работает хорошо и без сбоев. Также как проверить что код работает в фоне? (я зацикливал на 1000 записей, а в это время щёлкал по странице и элементам, страница не подвешивалась и можно сказать не подтормаживала. может быть есть какие-то средства специальные для этого?)
var app = angular
.module('contactList', ['lumx', 'ngSanitize', 'ngCsv', 'FredrikSandell.worker-pool'])
.run(function (WorkerService) {
//WorkerService.setAngularUrl('../bower_components/angular/angular.js');
WorkerService.setAngularUrl('https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js');
//WorkerService.addDependency(serviceName, moduleName, url);
});
app.controller('ReadFileController', ['$scope', '$http', 'WorkerService', function ($scope, $http, WorkerService) {
$scope.foo = function (content) {
var workerPromise = WorkerService.createAngularWorker(['input', 'output', '$http', function (input, output, $http) {
//var i=0;
//var callback = function(i) {
// output.notify();
// i++;
//};
//for (var i = 0; i < 1000; i++) { callback(i); }
output.notify();
}]);
workerPromise
.then(function success(angularWorker) {
//The input must be serializable
return angularWorker.run();
},
function error(reason) {
console.log('callback error');
console.log(reason);
//for some reason the worker failed to initialize
//not all browsers support the HTML5 tech that is required, see below.
}).then(function success(result) {
console.log('success');
console.log(result);
//handle result
}, function error(reason) {
//handle error
console.log('error');
console.log(reason);
}, function notify() {
//handle update
$http.post('/anguler-tasks-contacts/addContactData.php',{last_name:1, name:2, patronymic_name:3, address:4, telephone:5, url:6, description:7, completed:'false'})
.then(function(response) {
$scope.contactslist.push({
id: response.data[0].id,
last_name: response.data[0].last_name,
name: response.data[0].name,
patronymic_name: response.data[0].patronymic_name,
address: response.data[0].address,
telephone: response.data[0].telephone,
url: response.data[0].url,
description: response.data[0].description,
completed: response.data[0].completed
});
}
}
);
}
}]);
|
|
08.02.2017, 18:30
|
|
Профессор
|
|
Регистрация: 18.05.2011
Сообщений: 1,207
|
|
okuznetsov1,
Код твоего воркера находится в строчках с 14 по 24. Как видишь, твой воркер синхронно возвращает уведомление что он завершил работу и твой http запрос выполняется в основном потоке, т.е. ничего полезного воркер тут не делает как видишь.
Я подозреваю, что ты хотел выполнять запросы в теле воркера, следовательно тебе надо перенести строку 48 в тело воркера и оттуда в then коллбеке уведомлять главный поток, что запрос завершен и можно обновлять состояние contactslist.
$http.post('/anguler-tasks-contacts/addContactData.php',{last_name:1, name:2, patronymic_name:3, address:4, telephone:5, url:6, description:7, completed:'false'})
.then(function(response){
output.notify(response.data[0]);
})
function notify(data) {
...
}
Цитата:
|
может быть есть какие-то средства специальные для этого?)
|
Код создания воркера уже покрыт юнит тестами.
|
|
08.02.2017, 19:44
|
Аспирант
|
|
Регистрация: 02.11.2016
Сообщений: 65
|
|
Сообщение от destus
|
,
Я подозреваю, что ты хотел выполнять запросы в теле воркера, следовательно тебе надо перенести строку 48 в тело воркера и оттуда в then коллбеке уведомлять главный поток, что запрос завершен и можно обновлять состояние contactslist.
|
Да, в теле воркера. Я пробовал так как вы посоветовали, но получаю эту ошибку в Firefox: "Error: An invalid or illegal string was specified
rg/<@http://www.xxx.com/anguler-tasks-contacts/js/angular.min.js:106:201.........."
Если запускаю в Ghrome, то ошибка выглядит так: "XMLHttpRequest cannot load . Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource."
var app = angular
.module('contactList', ['lumx', 'ngSanitize', 'ngCsv', 'FredrikSandell.worker-pool'])
.run(function (WorkerService) {
//WorkerService.setAngularUrl('../bower_components/angular/angular.js');
WorkerService.setAngularUrl('https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js');
//WorkerService.addDependency(serviceName, moduleName, url);
});
app.controller('ReadFileController', ['$scope', '$http', 'WorkerService', function ($scope, $http, WorkerService) {
$scope.foo = function (content) {
var workerPromise = WorkerService.createAngularWorker(['input', 'output', '$http', function (input, output, $http) {
//var i=0;
//var callback = function(i) {
// output.notify();
// i++;
//};
//for (var i = 0; i < 1000; i++) { callback(i); }
$http.post('/anguler-tasks-contacts/addContactData.php',{last_name:1, name:2, patronymic_name:3, address:4, telephone:5, url:6, description:7, completed:'false'});
// $http.post('/anguler-tasks-contacts/addContactData.php',{last_name:1, name:2, patronymic_name:3, address:4, telephone:5, url:6, description:7, completed:'false'})
// .then(function(response){
// output.notify(response);
// });
}]);
workerPromise
.then(function success(angularWorker) {
//The input must be serializable
return angularWorker.run();
},
function error(reason) {
console.log('callback error');
console.log(reason);
//for some reason the worker failed to initialize
//not all browsers support the HTML5 tech that is required, see below.
}).then(function success(result) {
console.log('success');
console.log(result);
//handle result
}, function error(reason) {
//handle error
console.log('error');
console.log(reason);
}, function notify(response) {
//handle update
console.log(response.data[0]);
}
);
};
}]);
Последний раз редактировалось okuznetsov1, 08.02.2017 в 19:59.
Причина: убрал имя домена и более детально описал ошибку
|
|
08.02.2017, 21:42
|
Аспирант
|
|
Регистрация: 02.11.2016
Сообщений: 65
|
|
С этим разобрался, проблема оказалась из за того, что нужно явно было указать "http://", т.е. так:
$http.post('http://www.xxx.com/anguler-tasks-contacts/addContactData.php',{last_name:1, name:2, patronymic_name:3, address:4, telephone:5, url:6, description:7, completed:'false'});
|
|
08.02.2017, 21:56
|
Аспирант
|
|
Регистрация: 02.11.2016
Сообщений: 65
|
|
Сообщение от destus
|
okuznetsov1,
|
Не понимаю как внутри workera вызвать $scope-функцию angular-приложения, т.е. мне нужно вызвать функцию ($scope.parseCSV(content)) ?
............
$scope.foo = function (content) {
var workerPromise = WorkerService.createAngularWorker(['input', 'output', '$http', function (input, output, $http) {
var Items = parseCSV($content);
angular.forEach(Items, function (value, key) {
$http.post('http://www.xxx.com/anguler-tasks-contacts/addContactData.php',{last_name:value[1], name:value[2], patronymic_name:value[3], address:value[4], telephone:value[5], url:value[6], description:value[7], completed:'false'})
.then(function(response){
output.notify(response.data[0]);
});
});
}
}
............
Последний раз редактировалось okuznetsov1, 08.02.2017 в 22:50.
Причина: переформулировал вопрос
|
|
09.02.2017, 06:30
|
|
Профессор
|
|
Регистрация: 18.05.2011
Сообщений: 1,207
|
|
Цитата:
|
Не понимаю как внутри workera вызвать $scope-функцию angular-приложения, т.е. мне нужно вызвать функцию ($scope.parseCSV(content)) ?
|
One can not communicate data between worker and main thread by using service states. All communication must be done through the input object and output promise.
т.е. передавай функцию parseCSV в виде input.
|
|
09.02.2017, 14:51
|
Аспирант
|
|
Регистрация: 02.11.2016
Сообщений: 65
|
|
Сообщение от destus
|
One can not communicate data between worker and main thread by using service states. All communication must be done through the input object and output promise.
т.е. передавай функцию parseCSV в виде input.
|
т.е. мне нужно сделать как то так:
var param = new function() {
this.content = content;
this.funcParseCSV = "function parseCSV(input.content) { ........... }";
};
и передать в webworker:
return angularWorker.run(param);
а в worker-e уже как то так:
console.log( (new Function('', input.funcParseCSV))() );
|
|
09.02.2017, 15:03
|
|
Профессор
|
|
Регистрация: 18.05.2011
Сообщений: 1,207
|
|
okuznetsov1,
не понял этих костылей с new Function. Если мне надо передать просто функцию, то я её объявлю в основном потоке и передам параметром. А если нужно передать функцию и ещё что-то, то лучше сформировать объект и его передавать
var obj = {
parseCSV: $scope.parseCSV,
foo: 'bar'
}
angularWorker.run(obj)
|
|
|
|