Załóżmy, że utrzymujesz bibliotekę, która ujawnia funkcję getData
. Użytkownicy nazwać uzyskać rzeczywiste dane:
var output = getData();
Pod kaptur dane są zapisywane w pliku, dzięki czemu realizowane getData
przy użyciu node.js wbudowanej fs.readFileSync
. To oczywiste, że zarówno getData
i fs.readFileSync
są funkcjami synchronizacji. Pewnego dnia powiedziano Ci, aby przełączyć bazowe źródło danych do repozytorium, takiego jak MongoDB, do którego można uzyskać dostęp tylko asynchronicznie. Powiedziano ci również, abyś nie wkurzał swoich użytkowników, getData
API nie może zostać zmienione tak, aby zwracało jedynie obietnicę lub wymagało parametru wywołania zwrotnego. Jak spełniasz oba wymagania?
Funkcja asynchroniczna wykorzystująca wywołanie zwrotne / obietnicę to DNA języków JavasSript i Node.js. Każda nietrywialna aplikacja JS jest prawdopodobnie przesiąknięta tym stylem kodowania. Ale ta praktyka może łatwo doprowadzić do tak zwanej piramidy zagłady. Co gorsza, jeśli jakikolwiek kod w jakimkolwiek obiekcie wywołującym w łańcuchu wywołań zależy od wyniku funkcji asynchronicznej, ten kod również musi zostać opakowany w funkcję wywołania zwrotnego, nakładając na wywołującego ograniczenie stylu kodowania. Od czasu do czasu potrzebuję hermetyzowania funkcji asynchronicznej (często dostarczanej w bibliotece innej firmy) w funkcję synchronizacji, aby uniknąć masowego globalnego ponownego fakturowania. Poszukiwanie rozwiązania na ten temat zwykle kończyło się na Node Fiberslub pakiety npm pochodzące z niego. Ale włókna po prostu nie mogą rozwiązać problemu, z którym mam do czynienia. Nawet przykład podany przez autora Fibersa ilustruje brak:
...
Fiber(function() {
console.log('wait... ' + new Date);
sleep(1000);
console.log('ok... ' + new Date);
}).run();
console.log('back in main');
Rzeczywista wydajność:
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)
Jeśli funkcja Fiber naprawdę zmienia uśpienie funkcji asynchronicznej w synchronizację, wynik powinien wyglądać następująco:
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
Stworzyłem kolejny prosty przykład w JSFiddle i szukam kodu, który zapewni oczekiwane wyniki. Przyjmuję rozwiązanie, które działa tylko w Node.js, więc możesz wymagać dowolnego pakietu npm, mimo że nie działa w JSFiddle.