Я заметил это, пытаясь понять, почему заглушение системного времени привело к сбою записи csv. Оказывается, в библиотеке был блокирующий вызов setImmediate
: https://github.com/C2FO/fast-csv/blob/master/lib/extended.js#L18 .
Кажется, что есть куча библиотек, которые полагаются на setImmediate
для безобидных вещей, и подделка setImmediate
приводит к неожиданному поведению во всех из них:
Может быть, неразумно ожидать, что заглушка системного времени не приведет к сбою записи csv? В этом случае особенно трудно отследить, потому что в Javascript вы не можете просто нажать ctrl+c
и получить трассировку стека, показывающую, что пошло не так. Потребовалось около 90 минут только для того, чтобы определить, какая часть кода зависает, а затем понять, почему за это отвечает sinon.
Я не уверен, каким должно быть исправление, но, похоже, оно затрагивает множество библиотек, и по крайней мере одна из них отреагировала созданием собственной версии setImmediate
, с которой нельзя работать.
Если ответ: я должен звонить useFakeTimers(0, "Date")
, может быть, это должно быть по умолчанию? Может быть, это лучше соответствует моим ожиданиям/ожиданиям людей относительно того, как ведет себя мир?
Я не уверен, каким должно быть исправление, но похоже, что оно затрагивает множество библиотек, и по крайней мере одна из них отреагировала созданием собственной версии setImmediate, с которой нельзя работать.
Это рекомендуемое решение, когда вы используете setTimeout, setImmediate для эффекта получения нового стека вызовов (а не для управления временем).
Да, я только что потратил 90 минут на диагностику и исправление этого в коммерческой кодовой базе.
По крайней мере, в документах должно быть указано, что setImmediate будет подделан.
Для справки в будущем эта форма функции теперь позволяет указать, какие функции являются поддельными:
var clock = sinon.useFakeTimers([now, ]prop1, prop2, ...);
Sets the clock start timestamp and names functions to fake.
Possible functions are setTimeout, clearTimeout, setInterval, clearInterval, setImmediate, clearImmediate and Date. Can also be called without the timestamp.
Так что это решило проблему для меня при работе с экспрессом:
clock = sinon.useFakeTimers(1495020000, 'Date');
Документация объясняет это сейчас: http://sinonjs.org/releases/v2.3.2/fake-timers/#var -clock--sinonusefaketimersnow-prop1-prop2-
Самый полезный комментарий
Для справки в будущем эта форма функции теперь позволяет указать, какие функции являются поддельными:
Так что это решило проблему для меня при работе с экспрессом: