Page 244 - Браун Э. - Изучаем JavaScript. Руководство по созданию современных веб-сайтов - 2017
P. 244
бы хорошо иметь преимущества производительности асинхронных технологий без
дополнительных концептуальных трудностей? Вот где могут пригодиться генерато
ры.
Рассмотрим использованный ранее пример "проклятья обратных вызовов": чте
ние трех файлов, задержка на одну минуту и последующая запись содержимого пер
вых трех файлов одного за другим в четвертый файл. Наш человеческий разум хо
тел бы написать это в виде примерно такого псевдокода.
dataA читаем содержимое файла ' a . t xt '
dataB = читаем содержимое файла ' b . t xt '
dataC = читаем содержимое файла ' c . t xt '
Ждем 6 0 секунд
Записываем dataA + dataB + dataC в файл ' d . t xt '
Г е нераторы позволяют нам писать код, который выглядит очень похоже на этот ...
однако необходимые функциональные возможности не появятся как из коробки:
сначала придется проделать небольшую работу.
Первое, что необходимо, - это способ превратить функцию обратного вызова
с первым аргументом для передачи ошибки Node в обязательство. Мы инкапсулиру
ем это в функцию nfcall (Node function call - вызов функции Node).
function nfcall ( f , . . . args ) {
t
return new Promise ( f unc i on ( r esolve , rej ect ) {
(
f . call n u l l , . . . args , function ( err, . . . args )
i f ( e rr) return rej ect ( e rr) ;
s
resolve ( a rgs . length<2 ? args [ O ] : arg ) ;
} ) ;
} ) ;
Эта функция названа в честь метода nfc l l из библиотеки обяза
a
тельств Q (и реализована на его основе). Если вам необходимы эти
функциональные возможности, лучше всего воспользуйтесь библио
текой Q. Она включает не только этот метод, но и много других по-
лезных методов, также связанных с обязательствами. Я же представ
ляю реализацию nfcal l для демонстрации того, что никакого "вол
шебства" здесь нет.
Теперь мы можем преобразовать любой метод, написанный в стиле Node, так,
чтобы он получал обратный вызов для обязательства. Нам также понадобится функ
ция setTimeout, которая получает обратный вызов ... но поскольку она появилась
задолго до Node, она не соответствует соглашению о передаче ошибок функциям
обратного вызова. Поэтому необходимо создать новую функцию ptimeout (promise
timeout - период обязательства).
Генераторы 247

