Promise.resolve(), затем vs setImmediate vs nextTick
NodeJS 0.11, а также io.js и Node 0.12 ветвь всех кораблей с нативной promises.
Нативный promises имеет метод .then
, который всегда выполняется в цикле цикла будущих событий.
До сих пор я использовал setImmediate
для очереди на следующую итерацию цикла событий с тех пор, как я переключился с nextTick:
setImmediate(deferThisToNextTick); // My NodeJS 0.10 code
process.nextTick(deferThisToNextTick); // My NodeJS 0.8 code
Так как теперь у нас есть новый способ:
Promise.resolve().then(deferThisToNextTick);
Что я должен использовать? Кроме того, выполняет Promise.resolve.then
как setImmediate
или как nextTick
в отношении кода, выполняющегося до или после цикла события?
Ответы
Ответ 1
Использование Promise.resolve().then
не имеет преимуществ перед nextTick
. Он работает в одной очереди, но имеет несколько более высокий приоритет, то есть обработчик обещаний может предотвратить последующий вызов обратного звонка, противоположное невозможно. Это поведение является деталью реализации и на него нельзя полагаться.
Promise.resolve().then
, очевидно, медленнее (много, я думаю), потому что он создает два promises, которые будут выброшены.
Вы можете найти обширную информацию о реализации здесь: https://github.com/joyent/node/pull/8325
Самая важная часть: Promise.resolve().then
похожа на nextTick
и не нравится setImmediate
. Использование этого n места setImmediate
может кардинально изменить поведение вашего кода.
Ответ 2
Я не собираюсь отвечать на смелую часть о технических особенностях, но только вопрос
Что я должен использовать?
Я не думаю, что есть какая-то причина использовать Promise.resolve().then()
, если вы не заинтересованы в обещании результата вашей асинхронно выполняемой функции. Конечно, если вы, то это будет намного лучше, чем иметь дело с аддоном обратного вызова или сделать new Promise
из setTimeout
или nextTick
.
Там также есть вторая техническая разница, больше импорта, чем время: promises делать заглавные исключения. Который вы, вероятно, не хотите. Поэтому, как упоминалось в @vkurchatkin, не создавайте promises только для того, чтобы выбросить их. Не только потому, что он медленнее, но и потому, что он делает ваш код менее читаемым, а ваше приложение более подвержено ошибкам.
Ответ 3
Promise.resolve будет разрешен сразу (синхронно), а setImmediate явно прямо после выполнения текущего события.