Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 07.02.2017, 17:09
Аспирант
Отправить личное сообщение для okuznetsov1 Посмотреть профиль Найти все сообщения от okuznetsov1
 
Регистрация: 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);
            });

        };

}]);
Ответить с цитированием
  #2 (permalink)  
Старый 07.02.2017, 18:31
Аватар для destus
Профессор
Отправить личное сообщение для destus Посмотреть профиль Найти все сообщения от destus
 
Регистрация: 18.05.2011
Сообщений: 1,207

okuznetsov1,
Твой вебворкер запускается в другом потоке. То есть контекст воркера и ангуляр приложения полностью изолированы поэтому у тебя нет доступа к сервису $http.

Вот готовое решение https://github.com/FredrikSandell/angular-workers

Последний раз редактировалось destus, 07.02.2017 в 18:35.
Ответить с цитированием
  #3 (permalink)  
Старый 08.02.2017, 17:52
Аспирант
Отправить личное сообщение для okuznetsov1 Посмотреть профиль Найти все сообщения от okuznetsov1
 
Регистрация: 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
							});
							
						  }

                    }
                );
        }



	}]);
Ответить с цитированием
  #4 (permalink)  
Старый 08.02.2017, 18:30
Аватар для destus
Профессор
Отправить личное сообщение для destus Посмотреть профиль Найти все сообщения от destus
 
Регистрация: 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) {
...
}


Цитата:
может быть есть какие-то средства специальные для этого?)
Код создания воркера уже покрыт юнит тестами.
Ответить с цитированием
  #5 (permalink)  
Старый 08.02.2017, 19:44
Аспирант
Отправить личное сообщение для okuznetsov1 Посмотреть профиль Найти все сообщения от okuznetsov1
 
Регистрация: 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. Причина: убрал имя домена и более детально описал ошибку
Ответить с цитированием
  #6 (permalink)  
Старый 08.02.2017, 21:42
Аспирант
Отправить личное сообщение для okuznetsov1 Посмотреть профиль Найти все сообщения от okuznetsov1
 
Регистрация: 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'});
Ответить с цитированием
  #7 (permalink)  
Старый 08.02.2017, 21:56
Аспирант
Отправить личное сообщение для okuznetsov1 Посмотреть профиль Найти все сообщения от okuznetsov1
 
Регистрация: 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. Причина: переформулировал вопрос
Ответить с цитированием
  #8 (permalink)  
Старый 09.02.2017, 06:30
Аватар для destus
Профессор
Отправить личное сообщение для destus Посмотреть профиль Найти все сообщения от destus
 
Регистрация: 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.
Ответить с цитированием
  #9 (permalink)  
Старый 09.02.2017, 14:51
Аспирант
Отправить личное сообщение для okuznetsov1 Посмотреть профиль Найти все сообщения от okuznetsov1
 
Регистрация: 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))() );
Ответить с цитированием
  #10 (permalink)  
Старый 09.02.2017, 15:03
Аватар для destus
Профессор
Отправить личное сообщение для destus Посмотреть профиль Найти все сообщения от destus
 
Регистрация: 18.05.2011
Сообщений: 1,207

okuznetsov1,
не понял этих костылей с new Function. Если мне надо передать просто функцию, то я её объявлю в основном потоке и передам параметром. А если нужно передать функцию и ещё что-то, то лучше сформировать объект и его передавать
var obj = {
  parseCSV: $scope.parseCSV,
  foo: 'bar'
}
angularWorker.run(obj)
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Прошу раскритиковать наслойку работы с MySql. Alasdair Node.JS 4 21.11.2015 20:06
SQL запрос на языке JavaScript (не PHP) U_M0KRH Серверные языки и технологии 3 31.07.2015 05:06
SQL запрос. Как делать SELECT с условием SELECT Duda.Ml1986@gmail.com Серверные языки и технологии 16 13.01.2014 16:09
Не получается выполнить ajax запрос barfly jQuery 3 08.08.2012 13:52
Подставляем определенное значение в SQL запрос в зависмости от разрешения монитора MironM Общие вопросы Javascript 5 09.04.2012 21:54