É assim que eu acho que você deveria estar.
dividindo a corrente
Como as duas funções usarão amazingData , faz sentido tê-las em uma função dedicada. Normalmente faço isso sempre que quero reutilizar alguns dados, por isso está sempre presente como uma função arg.
Como seu exemplo está executando algum código, suponho que tudo esteja declarado dentro de uma função. Vou chamá-lo de toto () . Então teremos outra função que irá rodar afterSomething () e afterSomethingElse () .
function toto() {
return somethingAsync()
.then( tata );
}
Você também notará que adicionei uma declaração de retorno , pois geralmente é a maneira de proceder com as Promessas - você sempre retorna uma promessa para que possamos continuar o encadeamento, se necessário. Aqui, somethingAsync () produzirá amazingData e estará disponível em qualquer lugar dentro da nova função.
Agora, como essa nova função normalmente depende se processAsync () também é assíncrona ?
processAsync não assíncrono
Não há razão para complicar as coisas se processAsync () não for assíncrono. Algum bom código sequencial antigo faria isso.
function tata( amazingData ) {
var processed = afterSomething( amazingData );
return afterSomethingElse( amazingData, processed );
}
function afterSomething( amazingData ) {
return processAsync( amazingData );
}
function afterSomethingElse( amazingData, processedData ) {
}
Observe que não importa se afterSomethingElse () está fazendo algo assíncrono ou não. Em caso afirmativo, uma promessa será devolvida e a cadeia pode continuar. Se não for, o valor do resultado será retornado. Mas como a função é chamada a partir de um then () , o valor será empacotado em uma promessa de qualquer maneira (pelo menos em Javascript bruto).
processAsync assíncrono
Se processAsync () for assíncrono, o código será um pouco diferente. Aqui, consideramos afterSomething () e afterSomethingElse () não serão reutilizados em nenhum outro lugar.
function tata( amazingData ) {
return afterSomething()
.then( afterSomethingElse );
function afterSomething( /* no args */ ) {
return processAsync( amazingData );
}
function afterSomethingElse( processedData ) {
}
}
O mesmo que antes para afterSomethingElse () . Pode ser assíncrono ou não. Uma promessa será devolvida ou um valor embrulhado em uma promessa resolvida.
Seu estilo de codificação é bastante próximo ao que eu costumo fazer, por isso respondi mesmo depois de 2 anos. Não sou um grande fã de ter funções anônimas em todos os lugares. Acho difícil de ler. Mesmo que seja bastante comum na comunidade. É como substituímos o inferno de retorno por um purgatório de promessa .
Também gosto de manter o nome das funções no então curto. Eles só serão definidos localmente de qualquer maneira. E na maioria das vezes eles chamarão outra função definida em outro lugar - tão reutilizável - para fazer o trabalho. Eu até faço isso para funções com apenas 1 parâmetro, então não preciso colocar e tirar a função quando adiciono / removo um parâmetro à assinatura da função.
Comer exemplo
Aqui está um exemplo:
function goingThroughTheEatingProcess(plenty, of, args, to, match, real, life) {
return iAmAsync()
.then(chew)
.then(swallow);
function chew(result) {
return carefullyChewThis(plenty, of, args, "water", "piece of tooth", result);
}
function swallow(wine) {
return nowIsTimeToSwallow(match, real, life, wine);
}
}
function iAmAsync() {
return Promise.resolve("mooooore");
}
function carefullyChewThis(plenty, of, args, and, some, more) {
return true;
}
function nowIsTimeToSwallow(match, real, life, bobool) {
}
Não foque muito no Promise.resolve () . É apenas uma maneira rápida de criar uma promessa resolvida. O que tento conseguir com isso é ter todo o código que estou executando em um único local - logo abaixo do local . Todas as outras funções com um nome mais descritivo são reutilizáveis.
A desvantagem dessa técnica é que ela define muitas funções. Mas é uma dor necessária, receio, para não ter funções anônimas por todo lado. E qual é o risco de qualquer maneira: um estouro de pilha? (Piada!)
Usar matrizes ou objetos conforme definido em outras respostas também funcionaria. Essa de certa forma é a resposta proposta por Kevin Reid .
Você também pode usar bind () ou Promise.all () . Observe que eles ainda exigirão que você divida seu código.
usando ligação
Se você deseja manter suas funções reutilizáveis, mas não precisa realmente manter o que está dentro do então muito curto, você pode usar bind () .
function tata( amazingData ) {
return afterSomething( amazingData )
.then( afterSomethingElse.bind(null, amazingData) );
}
function afterSomething( amazingData ) {
return processAsync( amazingData );
}
function afterSomethingElse( amazingData, processedData ) {
}
Para mantê-lo simples, bind () adicionará a lista de args (exceto o primeiro) à função quando ela for chamada.
usando Promise.all
Em sua postagem, você mencionou o uso de spread () . Nunca usei a estrutura que você está usando, mas aqui está como você deve ser capaz de usá-la.
Alguns acreditam que Promise.all () é a solução para todos os problemas, então ele merece ser mencionado, eu acho.
function tata( amazingData ) {
return Promise.all( [ amazingData, afterSomething( amazingData ) ] )
.then( afterSomethingElse );
}
function afterSomething( amazingData ) {
return processAsync( amazingData );
}
function afterSomethingElse( args ) {
var amazingData = args[0];
var processedData = args[1];
}
Você pode passar dados para Promise.all () - observe a presença do array - contanto que as promessas, mas certifique-se de que nenhuma das promessas falhe, caso contrário, o processamento será interrompido.
E em vez de definir novas variáveis a partir do argumento args , você deve ser capaz de usar spread () em vez de then () para todo tipo de trabalho incrível.