Припустимо, ви підтримуєте бібліотеку, яка відкриває функцію getData
. Ваші користувачі називають його , щоб отримати фактичні дані:
var output = getData();
Під дані Ковпак зберігаються в файлі , так що ви реалізовані з getData
допомогою Node.js вбудованої fs.readFileSync
. Це очевидно і те, getData
і fs.readFileSync
функції синхронізації. Одного разу вам сказали переключити базове джерело даних на репо, наприклад MongoDB, до якого можна отримати доступ лише асинхронно. Вам також сказали, щоб не дратувати користувачів, getData
API не можна змінювати, щоб повернути лише обіцянку або вимагати параметр зворотного виклику. Як ви відповідаєте обом вимогам?
Асинхронною функцією, що використовує зворотній зв'язок / обіцянку, є ДНК JavasSript і Node.js. Будь-який нетривіальний додаток JS, ймовірно, пронизаний цим стилем кодування. Але ця практика може легко призвести до так званої піраміди зворотного виклику приреченості. Ще гірше, якщо будь-який код будь-якого абонента в ланцюзі викликів залежить від результату функції асинхронізації, цей код також повинен бути включений у функцію зворотного виклику, накладаючи обмеження стилю кодування на абонента. Час від часу я знаходжу необхідність інкапсулювати функцію асинхронізації (часто надану у сторонній бібліотеці) у функцію синхронізації, щоб уникнути масового глобального пере-факторингу. Пошук рішення на цю тему зазвичай закінчувався за допомогою волокон Nodeабо npm-пакети, отримані з нього. Але Волокна просто не можуть вирішити проблему, з якою я стикаюся. Навіть приклад, поданий автором Волокна, ілюстрував недолік:
...
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.