2014-12-18 2 views
0

У меня есть (возможно, тривиальный) вопрос. Я использую пакет Node.js async, и особенно метод async.each (https://github.com/caolan/async#forEach).Node.js async forEach: поточно-безопасный?

Рассмотрим следующий код:

var arrayOne=[]; 

async.forEach(arrayTwo, 
    function (item, callback){ 
    arrayOne.push(item); // push into arrayOne 
    callback(); // the iterator has completed 
    }, function(err) { 
    // do something with arrayOne 
}); 

Является arrayOne.push (пункт) сейф?

+4

Я думал, что все в node.js было поточно-безопасным - это однопоточная, управляемая событиями парадигма, нет? – Siler

+0

Вот что я знаю. Вот почему я сказал, что вопрос может быть тривиальным. Тем не менее, материал, который запускает async, все еще меня немного смущает. – ZzKr

+0

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

ответ

2

Итак, ответ здесь немного утончен. Для этого точного случая вы получите arrayOne, имеющие те же товары в том же порядке, что и arrayTwo, но это скорее побочный эффект вашего образца кода, который не является по-настоящему асинхронным, и async.forEach не делает ничего слишком неожиданного/умного. Однако, чтобы сделать это действительно надежным, вы хотите использовать функцию async, которая гарантирует заказ, который в письме договора .forEach/.each нет. .each гарантирует, что рабочая функция будет вызвана один раз с каждым элементом в arrayTwo. Это не гарантирует, что он запустит их все по порядку или дождитесь завершения одного из них до начала следующего и т. Д. Если автор async решил запустить рабочие функции в обратном порядке для некоторой оптимизации производительности, например, это изменит ваши побочные эффекты. Поэтому лучше не полагаться на какое-либо поведение, кроме того, что явно гарантировано в определении/документах для функции async. Итак, использование чего-то вроде async.series даст вам надежный способ сделать это и не получить неожиданный порядок в arrayOne в конце. Конечно, характеристики параллелизма теперь сильно различаются.

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

Самая полезная аналогия, которую я имею в виду, - это асинхронный код, заказывающий еду по доставке. Если вы позвоните в 3 ресторана и закажете одну пиццу у каждого, это не означает, какой заказ доставки доставит вам дверь.

+0

Спасибо за ответ. Моя главная проблема здесь заключается не в порядке, а в том, что две функции изменяют одну и ту же позицию в 'arrayOne', например, если оба пытаются нажать« arrayOne [0] ». Но, насколько я понял, это не проблема, так как 'node.js' имеет действительно только один поток. – ZzKr

+0

Да, нет проблемы с вызовом 'arrayOne.push'. –