Así es como creo que debería estar haciendo.
dividiendo la cadena
Debido a que ambas funciones usarán amazingData , tiene sentido tenerlas en una función dedicada. Por lo general, hago eso cada vez que quiero reutilizar algunos datos, por lo que siempre está presente como una función arg.
Como su ejemplo está ejecutando algún código, supongo que todo está declarado dentro de una función. Lo llamaré toto () . Luego tendremos otra función que se ejecutará tanto afterSomething () como afterSomethingElse () .
function toto() {
return somethingAsync()
.then( tata );
}
También notará que agregué una declaración de devolución , ya que generalmente es el camino a seguir con Promesas: siempre devuelve una promesa para que podamos seguir encadenando si es necesario. Aquí, somethingAsync () producirá datos asombrosos y estará disponible en todas partes dentro de la nueva función.
Ahora bien, ¿cómo se verá esta nueva función normalmente depende de si processAsync () también es asincrónico ?
processAsync no asincrónico
No hay razón para complicar demasiado las cosas si processAsync () no es asincrónico. Algún código secuencial bueno y antiguo lo haría.
function tata( amazingData ) {
var processed = afterSomething( amazingData );
return afterSomethingElse( amazingData, processed );
}
function afterSomething( amazingData ) {
return processAsync( amazingData );
}
function afterSomethingElse( amazingData, processedData ) {
}
Tenga en cuenta que no importa si afterSomethingElse () está haciendo algo asincrónico o no. Si lo hace, se devolverá una promesa y la cadena podrá continuar. Si no es así, se devolverá el valor del resultado. Pero debido a que la función se llama desde un then () , el valor se incluirá en una promesa de todos modos (al menos en Javascript sin formato).
processAsync asincrónico
Si processAsync () es asincrónico, el código se verá ligeramente diferente. Aquí consideramos que afterSomething () y afterSomethingElse () no se reutilizarán en ningún otro lugar.
function tata( amazingData ) {
return afterSomething()
.then( afterSomethingElse );
function afterSomething( /* no args */ ) {
return processAsync( amazingData );
}
function afterSomethingElse( processedData ) {
}
}
Lo mismo que antes para afterSomethingElse () . Puede ser asincrónico o no. Se devolverá una promesa o un valor envuelto en una promesa resuelta.
Su estilo de codificación es bastante parecido al que solía hacer, por eso respondí incluso después de 2 años. No soy un gran fanático de tener funciones anónimas en todas partes. Me cuesta leer. Incluso si es bastante común en la comunidad. Es como reemplazamos el infierno de devolución de llamada por un purgatorio de promesas .
También me gusta mantener el nombre de las funciones en el entonces corto. De todos modos, solo se definirán localmente. Y la mayoría de las veces llamarán a otra función definida en otro lugar, tan reutilizable, para hacer el trabajo. Incluso hago eso para funciones con solo 1 parámetro, por lo que no necesito que la función entre y salga cuando agrego / elimino un parámetro a la firma de la función.
Ejemplo de comer
Aquí hay un ejemplo:
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) {
}
No se centre demasiado en Promise.resolve () . Es solo una forma rápida de crear una promesa resuelta. Lo que trato de lograr con esto es tener todo el código que estoy ejecutando en una sola ubicación, justo debajo de los thens . Todas las demás funciones con un nombre más descriptivo son reutilizables.
El inconveniente de esta técnica es que define muchas funciones. Pero me temo que es un dolor necesario para evitar tener funciones anónimas por todas partes. ¿Y cuál es el riesgo de todos modos: un desbordamiento de pila? (¡broma!)
El uso de matrices u objetos como se define en otras respuestas también funcionaría. Esta de alguna manera es la respuesta propuesta por Kevin Reid .
También puede utilizar bind () o Promise.all () . Tenga en cuenta que aún requerirán que divida su código.
usando bind
Si desea mantener sus funciones reutilizables pero realmente no necesita mantener lo que está dentro del entonces muy corto, puede usar bind () .
function tata( amazingData ) {
return afterSomething( amazingData )
.then( afterSomethingElse.bind(null, amazingData) );
}
function afterSomething( amazingData ) {
return processAsync( amazingData );
}
function afterSomethingElse( amazingData, processedData ) {
}
Para mantenerlo simple, bind () antepondrá la lista de argumentos (excepto el primero) a la función cuando se llame.
usando Promise.all
En su publicación mencionó el uso de spread () . Nunca usé el marco que está usando, pero así es como debería poder usarlo.
Algunos creen que Promise.all () es la solución a todos los problemas, así que supongo que merece ser mencionado.
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];
}
Puede pasar datos a Promise.all () - tenga en cuenta la presencia de la matriz - siempre que las promesas, pero asegúrese de que ninguna de las promesas falle; de lo contrario, dejará de procesarse.
Y en lugar de definir nuevas variables a partir del argumento args , debería poder usar spread () en lugar de then () para todo tipo de trabajo increíble.