Como agrupar chamadas de funções assíncronas em uma função de sincronização no Node.js. ou Javascript?

Suponha que você mantenha uma biblioteca que exponha uma funçãogetData. Seus usuários ligam para obter dados reais:
var output = getData();
Os dados sob o capô são salvos em um arquivo para que você implementegetData usando o Node.js. internofs.readFileSync. É óbvio que ambosgetData efs.readFileSync são funções de sincronização. Um dia, foi solicitado que você alternasse a fonte de dados subjacente para um repositório como o MongoDB, que só pode ser acessado de forma assíncrona. Você também foi orientado a evitar irritar seus usuários,getData A API não pode ser alterada para retornar apenas uma promessa ou exigir um parâmetro de retorno de chamada. Como você atende aos dois requisitos?

A função assíncrona usando retorno de chamada / promessa é o DNA de JavasSript e Node.js. Qualquer aplicativo JS não trivial provavelmente é permeado por esse estilo de codificação. Mas essa prática pode facilmente levar à chamada pirâmide de destruição de retorno de chamada. Pior ainda, se qualquer código em qualquer chamador na cadeia de chamadas depende do resultado da função assíncrona, esse código também deve ser envolvido na função de retorno de chamada, impondo uma restrição de estilo de codificação ao chamador. De tempos em tempos, acho necessário encapsular uma função assíncrona (geralmente fornecida em uma biblioteca de terceiros) em uma função de sincronização para evitar uma re-fatoração global maciça. Procurar uma solução sobre esse assunto geralmente terminava comFibras do nó ou pacotes npm derivados dele. Mas as fibras simplesmente não conseguem resolver o problema que estou enfrentando. Mesmo o exemplo fornecido pelo autor da Fibers ilustrou a deficiência:

...
Fiber(function() {
    console.log('wait... ' + new Date);
    sleep(1000);
    console.log('ok... ' + new Date);
}).run();
console.log('back in main');

Saída real:

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)

Se a função Fiber realmente transformar a função assíncrona em suspensão em sincronização, a saída deverá ser:

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

Eu criei outro exemplo simples emJSFiddle e procurando por código para produzir a saída esperada. Aceitarei uma solução que só funciona no Node.js, assim você é livre para exigir qualquer pacote npm, apesar de não trabalhar no JSFiddle.

questionAnswers(10)

yourAnswerToTheQuestion