09.02.2017, 15:38
|
Аспирант
|
|
Регистрация: 02.11.2016
Сообщений: 65
|
|
Сообщение от destus
|
okuznetsov1,
не понял этих костылей с new Function. Если мне надо передать просто функцию, то я её объявлю в основном потоке и передам параметром. А если нужно передать функцию и ещё что-то, то лучше сформировать объект и его передавать
var obj = {
parseCSV: $scope.parseCSV,
foo: 'bar'
}
angularWorker.run(obj)
|
попробовал и получаю ошибку:
DOMException [DataCloneError: "The object could not be cloned."
code: 25
nsresult: 0x80530019
location: http://www.xxx.com/anguler-tasks-con...kers.min.js:1]
а если сделать так, то функция отрабатывает :
var param = { content: $fileContent, funcParseCSV: "function parseCSV(content) { console.log('ok'); } parseCSV();" };
angularWorker.run(obj);
а в воркере:
eval(input.funcParseCSV);
Но мне так не хотелось бы делать, т.к. лучше вариант - определить эту функцию внутри worker-a
Последний раз редактировалось okuznetsov1, 09.02.2017 в 15:41.
Причина: внёс небольшие поправки
|
|
09.02.2017, 16:35
|
|
Профессор
|
|
Регистрация: 18.05.2011
Сообщений: 1,207
|
|
okuznetsov1,
А, ну да, input -- сериализуемым оъектом должен быть, для ф-ции не подходит. Тогда твой 1 вариант, ок.
А зачем вообще эту ф-цию в scope объявлять и пытаться передавать? Может лучше сделать чистую функцию, объявить её в теле самого воркера и применять? А Content как раз передавать первым параметром run().
|
|
09.02.2017, 17:20
|
Аспирант
|
|
Регистрация: 02.11.2016
Сообщений: 65
|
|
Сообщение от destus
|
okuznetsov1,
А, ну да, input -- сериализуемым оъектом должен быть, для ф-ции не подходит. Тогда твой 1 вариант, ок.
А зачем вообще эту ф-цию в scope объявлять и пытаться передавать? Может лучше сделать чистую функцию, объявить её в теле самого воркера и применять? А Content как раз передавать первым параметром run().
|
Я вчера ещё объявил эту функцию в теле воркера и применял, всё работало и думал на этом варианте остановиться. Но поразмыслив, пришёл к выводу, что на всякий случай лучше передавать эту функцию в воркер, т.к. в ближайшем будущем в функционале системы могут появится ещё воркеры которые будут использовать эту же функцию, и придётся её дублировать.
вроде получилось как хотел, сделал так:
передаю в воркер:
var bodyFuncParseCSV = eval($scope.parseCSV).toString();
var param = { content: $fileContent, funcParseCSV: bodyFuncParseCSV };
return angularWorker.run(param);
в теле воркера вызываю так:
var Items = eval('var parseCSV = ' + input.funcParseCSV + '; parseCSV(input.content);');
Не знаю костыль это или нет, как вы считаете?
|
|
09.02.2017, 17:27
|
|
Профессор
|
|
Регистрация: 18.05.2011
Сообщений: 1,207
|
|
okuznetsov1,
обычно eval не рекомендуют к использованию.
Цитата:
|
в ближайшем будущем в функционале системы могут появится ещё воркеры которые будут использовать эту же функцию, и придётся её дублировать.
|
А что мешает выделить эту функцию в тело отдельного воркера и запускать его когда нужно? Т.е. сначала запускается воркер, который обладает функциональностью parseCSV, а когда он распарсит, в его коллбэке вызывать другой воркер, который будет делать http запрос на основе этих данных?
|
|
09.02.2017, 18:53
|
Аспирант
|
|
Регистрация: 02.11.2016
Сообщений: 65
|
|
Сообщение от destus
|
okuznetsov1,
обычно eval не рекомендуют к использованию.
А что мешает выделить эту функцию в тело отдельного воркера и запускать его когда нужно? Т.е. сначала запускается воркер, который обладает функциональностью parseCSV, а когда он распарсит, в его коллбэке вызывать другой воркер, который будет делать http запрос на основе этих данных?
|
Ваш данный вариант то что нужно. А не могли бы вы на небольшом примере показать как это реализовать (хотя бы схематично)? Я не могу разобраться как запустить второй воркер в коллбэке
|
|
10.02.2017, 06:41
|
|
Профессор
|
|
Регистрация: 18.05.2011
Сообщений: 1,207
|
|
okuznetsov1,
$scope.content = 'blabla';
var workerPromise1 = WorkerService.createAngularWorker(['input', 'output',
function(input, output) {
function parseCSV(input){
/* body parseCSV */
return parseInput
}
output.notify(parseCSV(input));
}]);
var workerPromise2 = WorkerService.createAngularWorker(['input', 'output', '$http',
function(input, output, $http) {
angular.forEach(input, 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]);
});
});
}]);
workerPromise1.then(function success(angularWorker) {
//The input must be serializable
return angularWorker.run($scope.content);
}, function error(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) {
//handle result
}, function error(reason) {
//handle error
}, function notify(Items) {
workerPromise2.then(function(angularWorker){
return angularWorker.run(Items)
}).then(
function(){},
function(){},
function notify(response){console.log(response)}
)
});
|
|
10.02.2017, 16:28
|
Аспирант
|
|
Регистрация: 02.11.2016
Сообщений: 65
|
|
Сообщение от destus
|
okuznetsov1,
$scope.content = 'blabla';
var workerPromise1 = WorkerService.createAngularWorker(['input', 'output',
function(input, output) {
function parseCSV(input){
/* body parseCSV */
return parseInput
}
output.notify(parseCSV(input));
}]);
var workerPromise2 = WorkerService.createAngularWorker(['input', 'output', '$http',
function(input, output, $http) {
angular.forEach(input, 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]);
});
});
}]);
workerPromise1.then(function success(angularWorker) {
//The input must be serializable
return angularWorker.run($scope.content);
}, function error(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) {
//handle result
}, function error(reason) {
//handle error
}, function notify(Items) {
workerPromise2.then(function(angularWorker){
return angularWorker.run(Items)
}).then(
function(){},
function(){},
function notify(response){console.log(response)}
)
});
|
Спасибо, очень мне помогли.
Но сейчас из всего вышесказанного у меня возник ещё один вопрос (наверное последний):
У меня возникла необходимость (как ранее я и предполагал) задействовать 2-ой воркер (workerPromise2) для расширения функционала системы. В свзи с этим возник вопрос - "как можно запустить второй воркер из другого контроллера", возможно ли такое? Сейчас я продублировал код 2-го воркера в другом контроллере. Но такое решение разумеется мне не нравится.
По сути в другом контроллере я разместил такой же код (что вы прислали в последнем сообщении), выглядит так:
app.controller('MainController', ['$scope', 'WorkerService', 'LxNotificationService', '$http', '$log', function($scope, WorkerService, LxNotificationService, $http, $log) {
$scope.content = 'blabla';
$scope.addContact = function() {
var workerPromise2 = WorkerService.createAngularWorker(['input', 'output', '$http',
function(input, output, $http) {
angular.forEach(input, 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]);
});
});
}]);
workerPromise2.then(function(angularWorker){
return angularWorker.run(Items)
}).then(
function(){},
function(){},
function notify(response){console.log(response)}
)
};
}]);
Последний раз редактировалось okuznetsov1, 10.02.2017 в 16:42.
Причина: внёс коррективы более подробные (последние)
|
|
10.02.2017, 17:06
|
|
Профессор
|
|
Регистрация: 18.05.2011
Сообщений: 1,207
|
|
okuznetsov1,
А может лучше тогда в сервисе этот код воркера обьявить, инжектить сервис в каждый контроллер и оттуда вызывать?
|
|
20.02.2017, 18:44
|
Аспирант
|
|
Регистрация: 02.11.2016
Сообщений: 65
|
|
спасибо
|
|
|
|