Как сделать эту JS-функцию асинхронной?
function takesTime(){
for (var i = 0; i<some_very_large_number; i++){
//do something synchronous
}
console.log('a');
}
takesTime();
console.log('b');
Отпечатки:
б
Как бы вы сделали печать:
б
а
Ответы
Ответ 1
Я вижу, что это помечено node.js, поэтому я отвечу на него с этой точки зрения: вы не должны. Обычно, если вы блокируете, это будет: network-bound (вы должны использовать и/или повторно использовать сетевые библиотеки вокруг асинхронных методов), I/O-bound (вы должны использовать и/или повторно использовать библиотеки ввода-вывода) или привязанные к CPU. Вы не указали какой-либо контекст для того, что является долгосрочной задачей, и учитывая, что у вас есть инвариант цикла, содержащий some_very_large_number
, я предполагаю, что вы представляете себе задачу, требующую большого количества CPU, выполняющую итерацию по большому полю.
Если вы на самом деле связаны с процессором, вы должны пересмотреть свою стратегию. Node живет только на одном ядре, поэтому даже если вы сможете использовать многопоточность, вы действительно просто вращаете свои колеса, так как каждый запрос по-прежнему требует определенного количества процессорного времени. Если вы действительно намереваетесь делать что-то вычислительно-интенсивное, вы можете захотеть изучить систему очередей и иметь что-то другое, обрабатывая данные, которые лучше предназначен для его хрустания.
Ответ 2
for (var i = 0; i < someVeryLargeNumber; ++i) {
setTimeout(function () {
//do something synchronous
}, 0);
}
Также см. setZeroTimeout, чтобы получить несколько миллисекунд за каждый цикл, хотя работающие люди делают это, похоже, на основе браузера.
Ответ 3
Javascript основан на событиях, и все происходит в одном потоке. Способ сделать его "асинхронным" - использовать таймаут (setTimeout()).
Ответ 4
Вы можете использовать веб-работников для достижения своей цели, но для этого вам потребуется отдельный файл js, и вам нужно будет добавить сантехнический код для публикации сообщений и обработки этих сообщений.
node.js не поддерживает веб-работников изначально, но реализация доступна по адресу:
https://github.com/cramforce/node-worker/
В противном случае это похоже на следующий код:
var pid = require('child_process').spawn('node', ['childScript.js'])
pid.stdout.on('data', function(data) {
console.log(data);
});
console.log('b');
childScript.js
for (var i = 0; i < some_very_large_number; i++) {
// do something synchronous
}
console.log('a');