2017-01-20 3 views
1

У меня этот код периодически вызывает функцию load, которая очень загружает работу с 10 секунд. Проблема заключается в том, когда выполняется функция load, она блокирует основной поток. Если я отправлю простой запрос GET (например, проверку работоспособности), пока выполняется load, вызов GET блокируется до тех пор, пока вызов load не будет завершен.Как создать функцию для работы на фоне?

function setLoadInterval() { 
    var self = this; 
    this.interval = setInterval(function doHeavyWork() { 
     // this takes 10 sec 
     self.load(); 
     self.emit('reloaded'); 
    }, 20000); 

Я пробовал async.parallel, но все же вызов GET был заблокирован. Я попробовал setTimeout, но получил тот же результат. Как сделать load для работы на фоне, чтобы он не блокировал основной поток?

this.interval = setInterval(function doHeavyWork() { 
    async.parallel([function(cb) { 
     self.load(); 
     cb(null); 
    }], function(err) { 
     if (err) { 
     // log error 
     } 
     self.emit('reloaded'); 
    }) 
}, 20000); 
+1

Что делает 'self.load();' это занимает 10 секунд? Я имею в виду, если это можно сделать в отдельном процессе, просто используйте один из fork | spawn | exec таким образом, чтобы он не блокировал цикл событий. – Molda

+0

он считывает пары значений ключей 1M на карте и выполняет некоторую фильтрацию. – codereviewanskquestions

+0

Итак, вопрос в том, нет ли лучшего способа сделать то, что вам нужно? Если данные взяты из БД, почему бы вам не позволить своему db работать на вас? Если вы можете быть более конкретным, возможно, есть и другой способ сделать это. – Molda

ответ

1

Node.js является управляемыми событиями неблокирующей IO моделируют

Все, что есть IO выгружаются как отдельный поток в основном двигателе и, следовательно, параллелизм достигается. Если задача сосредоточена на процессоре, вы не можете добиться параллелизма, поскольку по умолчанию Javascript является блокирующим языком синхронизации.

Однако есть некоторые способы достижения этой цели путем разгрузки задачи интенсивного процессора на другой процесс.

опция1: функция
Exec или породить дочерний процесс и выполнить загрузку() в том, что породил приложение узла. Это нормально, если интервал срабатывает на каждые 20000 мс, так как к тому времени, когда будет запущен другой, процесс 10 секунд будет завершен.
В противном случае это опасно, так как это может породить слишком много приложений узла съедает ваши системы ресурсы

option2: Я не знаю, как много self.load данных() принимает и возвращает. Если это тривиально, и сетевые накладные расходы приемлемы, сделайте эту задачу сбалансированной по нагрузке веб-службой (может быть 4 веб-сервера, работающими параллельно), которая принимает (точнее указывает) 1M записи и возвращает обратно отфильтрованные записи.

ПРИМЕЧАНИЕ
Похоже, что вы используете узел асинхронной параллельной функции. Но обратите внимание на это описание из документации.

Примечание. Параллель идет о стартовых задачах ввода-вывода параллельно, а не о параллельном выполнении кода. Если ваши задачи не используют таймеры или не выполняют никаких операций ввода-вывода, они будут выполняться последовательно. Любые синхронные разделы настройки для каждой задачи будут происходить один за другим. JavaScript остается однопоточным.

 Смежные вопросы

  • Нет связанных вопросов^_^