Ось як я вважаю, що ти повинен робити.
розщеплення ланцюга
Оскільки обидві функції будуть використовувати amazingData , має сенс мати їх у виділеній функції. Зазвичай я роблю це щоразу, коли хочу повторно використовувати деякі дані, тому вони завжди присутні як аргумент функції.
Оскільки у вашому прикладі працює якийсь код, я вважаю, що все це оголошено всередині функції. Я називатиму це toto () . Тоді у нас буде інша функція, яка буде працювати як afterSomething (), так і afterSomethingElse () .
function toto() {
return somethingAsync()
.then( tata );
}
Ви також помітите, що я додав заяву про повернення, оскільки зазвичай це спосіб іти в Promises - ви завжди повертаєте обіцянку, щоб ми могли продовжувати ланцюжок, якщо потрібно. Тут щосьAsync () створить дивовижні дані, і це буде доступно всюди в новій функції.
Тепер, як буде виглядати ця нова функція, як правило, залежить від того , що processAsync () також асинхронний ?
processAsync не асинхронний
Немає причин занадто ускладнювати речі, якщо processAsync () не є асинхронним. Це зробить якийсь старий хороший послідовний код.
function tata( amazingData ) {
var processed = afterSomething( amazingData );
return afterSomethingElse( amazingData, processed );
}
function afterSomething( amazingData ) {
return processAsync( amazingData );
}
function afterSomethingElse( amazingData, processedData ) {
}
Зауважте, що не має значення, чи afterSomethingElse () робить щось асинхронне чи ні. Якщо це станеться, обіцянка буде повернута, і ланцюжок може продовжуватися. Якщо це не так, тоді буде повернуто значення результату. Але оскільки функція викликана з then () , значення все одно буде перетворено в обіцянку (принаймні в необробленому Javascript).
processAsync асинхронний
Якщо processAsync () асинхронний, код буде виглядати дещо інакше. Тут ми розглядаємо afterSomething () та afterSomethingElse (), які більше ніде не будуть використані.
function tata( amazingData ) {
return afterSomething()
.then( afterSomethingElse );
function afterSomething( /* no args */ ) {
return processAsync( amazingData );
}
function afterSomethingElse( processedData ) {
}
}
Те саме, що і для afterSomethingElse () . Це може бути асинхронно чи ні. Буде повернуто обіцянку або вартість, обернуту вирішеною обіцянкою.
Ваш стиль кодування досить близький до того, що я звик робити, тому я відповів навіть через 2 роки. Я не шанувальник анонімних функцій скрізь. Мені важко читати. Навіть якщо це досить поширене явище в громаді. Це як ми замінили зворотний дзвінок пеклом на чистилище обіцянок .
Мені також подобається вказувати назву функцій у тоді короткому. Вони все одно будуть визначені лише локально. І більшу частину часу вони будуть викликати іншу функцію, визначену в іншому місці - настільки багаторазову - для виконання цієї роботи. Я навіть роблю це для функцій лише з 1 параметром, тому мені не потрібно вводити та виводити функцію, коли я додаю / видаляю параметр до підпису функції.
Приклад харчування
Ось приклад:
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) {
}
Не зосереджуйтесь надто на Promise.resolve () . Це лише швидкий спосіб створити вирішену обіцянку. Я намагаюся досягти цим, щоб весь код, який я запускаю, знаходився в одному місці - безпосередньо під тенами . Всі інші функції з більш описовою назвою багаторазові.
Недоліком цієї техніки є те, що вона визначає безліч функцій. Але я боюся, що це необхідний біль, щоб уникнути анонімних функцій повсюдно. І який взагалі ризик: переповнення стека? (жарт!)
Використання масивів або об’єктів, як визначено в інших відповідях, також спрацювало б. Це певним чином є відповіддю, запропонованою Кевіном Рід .
Ви також можете використовувати bind () або Promise.all () . Зверніть увагу, що вони все одно вимагатимуть розділити ваш код.
за допомогою bind
Якщо ви хочете зберегти свої функції багаторазовим, але вам насправді не потрібно тримати те, що знаходиться всередині, тоді дуже коротким, ви можете використовувати bind () .
function tata( amazingData ) {
return afterSomething( amazingData )
.then( afterSomethingElse.bind(null, amazingData) );
}
function afterSomething( amazingData ) {
return processAsync( amazingData );
}
function afterSomethingElse( amazingData, processedData ) {
}
Щоб зробити це просто, bind () додасть список аргументів (крім першого) до функції, коли вона буде викликана.
за допомогою Promise.all
У своєму дописі ви згадали використання поширення () . Я ніколи не використовував фреймворк, який ви використовуєте, але ось як ви повинні мати змогу ним користуватися.
Деякі вважають, що Promise.all () є рішенням усіх проблем, тому, мабуть, він заслуговує на це згадки.
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];
}
Ви можете передавати дані Promise.all () - зауважте наявність масиву - поки обіцянки, але переконайтеся, що жодна з обіцянок не провалиться, інакше вона припинить обробку.
І замість того, щоб визначати нові змінні з аргументу args , ви повинні мати можливість використовувати spread () замість then () для будь-якої чудової роботи.