Вот как, я думаю, вы должны поступать.
разрыв цепи
Поскольку обе функции будут использовать amazingData , имеет смысл разместить их в специальной функции. Обычно я делаю это каждый раз, когда хочу повторно использовать некоторые данные, поэтому они всегда представлены как функция arg.
Поскольку в вашем примере выполняется некоторый код, я предполагаю, что все это объявлено внутри функции. Я назову это toto () . Тогда у нас будет еще одна функция, которая будет запускаться как afterSomething (), так и afterSomethingElse () .
function toto() {
return somethingAsync()
.then( tata );
}
Вы также заметите, что я добавил оператор return, поскольку это обычно способ использовать Promises - вы всегда возвращаете обещание, поэтому мы можем продолжить цепочку при необходимости. Здесь somethingAsync () будет создавать amazingData, и они будут доступны везде внутри новой функции.
Теперь, как будет выглядеть эта новая функция, обычно зависит от того, является ли 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 года. Я не большой поклонник анонимных функций везде. Мне трудно читать. Даже если это довольно распространено в обществе. Это , как мы заменили обратный вызов-ад пути в обещании-чистилище .
Я также хотел бы сохранить имя функции в то короткое. В любом случае они будут определены только локально. И большую часть времени они будут вызывать другую функцию, определенную где-то в другом месте - так многоразовую - для выполнения этой работы. Я даже делаю это для функций с одним параметром, поэтому мне не нужно вводить и отключать функцию, когда я добавляю / удаляю параметр в сигнатуре функции.
Пример еды
Вот пример:
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 () .
function tata( amazingData ) {
return afterSomething( amazingData )
.then( afterSomethingElse.bind(null, amazingData) );
}
function afterSomething( amazingData ) {
return processAsync( amazingData );
}
function afterSomethingElse( amazingData, processedData ) {
}
Для простоты bind () добавит список аргументов (кроме первого) к функции при ее вызове.
используя Promise.all
В своем посте вы упомянули об использовании spread () . Я никогда не использовал фреймворк, который вы используете, но вот как вы сможете его использовать.
Некоторые считают, что 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 () для всякого рода отличной работы.