Как запустить функцию в фоновом режиме [дублировать]

import org.apache.hadoop.fs.{FileAlreadyExistsException, FileSystem, FileUtil, Path}

val srcFileSystem: FileSystem = FileSystemUtil
  .apply(spark.sparkContext.hadoopConfiguration)
  .getFileSystem(sourceFile)
val dstFileSystem: FileSystem = FileSystemUtil
  .apply(spark.sparkContext.hadoopConfiguration)
  .getFileSystem(sourceFile)
FileUtil.copy(
  srcFileSystem,
  new Path(new URI(sourceFile)),
  dstFileSystem,
  new Path(new URI(targetFile)),
  true,
  spark.sparkContext.hadoopConfiguration)
69
задан arg20 23 May 2013 в 13:26
поделиться

5 ответов

Общение с веб-рабочими происходит через механизм обмена сообщениями. Перехват этих сообщений происходит при обратном вызове. В AngularJS лучшее место для размещения веб-рабочего - это услуга, которую вы должным образом заметили. Лучший способ справиться с этим - использовать обещания, с которыми Угловая работает удивительно.

Вот пример 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 или выполнил бы обработку прямо там.

Надеюсь, это имеет смысл.

94
ответ дан Eric G 25 August 2018 в 15:35
поделиться

Угловой веб-рабочий с примером опроса

Когда вы работаете с рабочими в 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

7
ответ дан Chanakya Vadla 25 August 2018 в 15:35
поделиться

Очень интересный вопрос! Я нахожу спецификацию веб-работника немного неудобной (вероятно, по уважительным причинам, но все еще неловкой). Необходимость сохранения кода работника в отдельном файле делает работу с сервисом трудной для чтения и представляет зависимости от статических URL-адресов файлов в вашем угловом коде приложения. Эту проблему можно смягчить, используя URL.createObjectUrl (), который можно использовать для создания URL-адреса для строки JavaScript. Это позволяет нам указать рабочий код в том же файле, который создает рабочего.

var blobURL = URL.createObjectURL(new Blob([
    "var i = 0;//web worker body"
], { type: 'application/javascript' }));
var worker = new Worker(blobURL);

Спецификация веб-работника также позволяет полностью изолировать контекст рабочего и основного потока, чтобы предотвратить ситуации, связанные с блокировками и livelocks и т. Д. происходят. Но это также означает, что у вас не будет доступа к вашим угловым услугам у рабочего без какой-либо вопли. Работник испытывает недостаток в некоторых вещах, которые мы (и угловатые) ожидаем при выполнении JavaScript в браузере, таких как глобальная переменная «документ» и т. Д. «Издеваясь над этими требуемыми функциями браузера у работника мы можем получить угловое действие.

var window = self;
self.history = {};
var document = {
    readyState: 'complete',
    cookie: '',
    querySelector: function () {},
    createElement: function () {
        return {
            pathname: '',
            setAttribute: function () {}
        };
    }
};

Некоторые функции, очевидно, не будут работать, привязки к DOM и т. д. Но инфраструктура инъекции и, например, служба $ http будут работать очень хорошо, что, вероятно, является тем, что мы хотим в рабочем месте. Что мы получаем от этого, так это то, что мы можем запускать стандартные угловые сервисы у рабочего. Поэтому мы можем тестировать службы, используемые в рабочем месте, так же, как и с любой другой угловой зависимостью.

Я сделал сообщение, которое более подробно описывает это здесь и создало github repo, который создает службу, которая реализует идеи, описанные выше здесь

16
ответ дан liket 25 August 2018 в 15:35
поделиться

Я нашел полностью рабочий пример веб-работников в 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;
    });

}]);

Он использует обещания ждать, пока рабочий вернет результат.

11
ответ дан Octane 25 August 2018 в 15:35
поделиться

вы также можете взглянуть на угловой плагин 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 doc: http://www.eslinstructor.net/ng-vkthread/demo/

- Вадим

2
ответ дан vadimk 25 August 2018 в 15:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: