Предположим, вы поддерживаете библиотеку, которая предоставляет функцию getData
. Ваши пользователи называют его , чтобы получить фактические данные:
var output = getData();
Под данные Колпак сохраняются в файле , так что вы реализованы с getData
помощью Node.js встроенной fs.readFileSync
. Очевидно, что обе функции getData
и fs.readFileSync
являются функциями синхронизации. Однажды вам сказали переключить базовый источник данных на репо, например MongoDB, к которому можно получить доступ только асинхронно. Вам также сказали, чтобы вы не злили своих пользователей, getData
API нельзя изменить так, чтобы он возвращал просто обещание или запрашивал параметр обратного вызова. Как вы соответствуете обоим требованиям?
Асинхронная функция с использованием обратного вызова / обещания - это ДНК JavasSript и Node.js. Любое нетривиальное JS-приложение, вероятно, пронизано этим стилем кодирования. Но такая практика легко может привести к так называемой пирамиде гибели обратных вызовов. Хуже того, если какой-либо код в любом вызывающем абоненте в цепочке вызовов зависит от результата асинхронной функции, этот код также должен быть заключен в функцию обратного вызова, налагая ограничение стиля кодирования на вызывающего. Время от времени я обнаруживаю необходимость инкапсулировать асинхронную функцию (часто предоставляемую в сторонней библиотеке) в функцию синхронизации, чтобы избежать массового глобального повторного факторинга. Поиск решения по этому поводу обычно заканчивался Node Fibers.или пакеты npm, производные от него. Но Fibers просто не могут решить проблему, с которой я столкнулся. Даже пример, приведенный автором Фиберса, иллюстрирует этот недостаток:
...
Fiber(function() {
console.log('wait... ' + new Date);
sleep(1000);
console.log('ok... ' + new Date);
}).run();
console.log('back in main');
Фактический выход:
wait... Fri Jan 21 2011 22:42:04 GMT+0900 (JST)
back in main
ok... Fri Jan 21 2011 22:42:05 GMT+0900 (JST)
Если функция Fiber действительно превращает спящий режим асинхронной функции в синхронизацию, вывод должен быть:
wait... Fri Jan 21 2011 22:42:04 GMT+0900 (JST)
ok... Fri Jan 21 2011 22:42:05 GMT+0900 (JST)
back in main
Я создал еще один простой пример в JSFiddle и ищу код для получения ожидаемого результата. Я приму решение, которое работает только в Node.js, поэтому вы можете потребовать любой пакет npm, несмотря на то, что он не работает в JSFiddle.