Как лучше всего разрабатывать код, который может работать с асинхронными функциями внутри функций обратного вызова, вот упрощенный взгляд на проблему.
Существуют эти функции обновления, которые вызывают некоторые асинхронные вызовы функций для обновления некоторых данных в каком-либо хранилище.
function update(){
asyncfn(arg, () => {// Callback code});
}
то есть эти две кнопки для вызова функции обновления
Updatebtn.onClick = update;
UpdateDisplaybtn.onClick = () => {
update();
displayUpdatedData();
}
Вторая кнопка вызовет проблемы, так как displayUpdatedData() будет вызываться до того, как update() действительно завершится, поскольку у него есть асинхронный вызов функции, который не будет завершен, также я не могу указать свой собственный обратный вызов в update(), поскольку он используется в качестве обратного вызова для события onClick.
Я мало что знаю о промисах, но знаю, что используемые мной асинхронные функции их не поддерживают.
Я не ищу какой-то обходной путь, я ищу лучшую практику в такой ситуации.
ОБНОВИТЬ
Узнав, что лучше всего использовать обещания, я использовал этот плейлист YouTube «Обещания JavaScript» от The Coding Train, чтобы узнать о них, что было очень хорошо, и я хотел поделиться им со всеми, кто хочет узнать о обещаниях.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Поэтому, если вы ищете лучшие практики, я настоятельно рекомендую вам ознакомиться с обещаниями. Javascript теперь поддерживает синтаксис async/await, который позволяет вам ждать ответа промисов, но позволяет вам писать свой код более или менее как обычную функцию. Я знаю, вы говорите, что асинхронные функции, которые вы хотите использовать, требуют обратных вызовов и не поддерживают обещания, но вы можете преобразовать функцию, основанную на обратном вызове, в функцию, основанную на обещании (обещание), используя библиотеки, такие как bluebird, или если вы находитесь в узле, у него есть собственная функция обещания.
Тогда у вас получится что-то вроде этого:
import cbFn from 'cbFn'; //import or require your callback based function
import {promisify} from 'util';
const pFn = promisify(cbFn);
async function update() {
await pFn()
}
...
UpdateDisplaybtn.onClick = async () => {
await update();
await displayUpdatedData() //await only needed if displayUpdatedData is also async / a promise
}
Я бы не стал использовать термин «синтаксический сахар» (термин TypeScript). async / await — это 100% родной синтаксис JS.
Обновлено. Я все еще привык думать об этом с точки зрения того, когда нам нужно было иметь транспилеры для async/await.
Если вы работаете с функцией, которая принимает только обратный вызов, вы можете обернуть ее внутри промиса, чтобы использовать async/await. Если функция уже возвращает промис, вы можете просто использовать async / await без необходимости оборачивать его.
Делая это таким образом, вы все еще можете последовательно выполнять свои функции update и displayUpdatedData, просто помещая их в функцию async и awaiting их.
function callbackFunction (cb) {
// ... stuff is happening
cb('Data from the callback func');
}
async function update() {
return new Promise( (resolve, reject) => {
callbackFunction( (data) => {
resolve(data); // or reject(); if failure
});
});
}
const doThings = async () => {
const result = await update();
console.info(result);
// TODO: Display data from the result
};
doThings();
Не могли бы вы просто сделать анонимную функцию для
UpdateDisplaybtn.onClickфункциейasync, а затемawaitвызватьupdate()?