Разработка обратных вызовов функций с помощью асинхронных вызовов

Как лучше всего разрабатывать код, который может работать с асинхронными функциями внутри функций обратного вызова, вот упрощенный взгляд на проблему.


Существуют эти функции обновления, которые вызывают некоторые асинхронные вызовы функций для обновления некоторых данных в каком-либо хранилище.

function update(){
  asyncfn(arg, () => {// Callback code});
}

то есть эти две кнопки для вызова функции обновления

Updatebtn.onClick = update;

UpdateDisplaybtn.onClick = () => {
  update();
  displayUpdatedData();
}

Вторая кнопка вызовет проблемы, так как displayUpdatedData() будет вызываться до того, как update() действительно завершится, поскольку у него есть асинхронный вызов функции, который не будет завершен, также я не могу указать свой собственный обратный вызов в update(), поскольку он используется в качестве обратного вызова для события onClick.

Я мало что знаю о промисах, но знаю, что используемые мной асинхронные функции их не поддерживают.

Я не ищу какой-то обходной путь, я ищу лучшую практику в такой ситуации.


ОБНОВИТЬ

Узнав, что лучше всего использовать обещания, я использовал этот плейлист YouTube «Обещания JavaScript» от The Coding Train, чтобы узнать о них, что было очень хорошо, и я хотел поделиться им со всеми, кто хочет узнать о обещаниях.

Не могли бы вы просто сделать анонимную функцию для UpdateDisplaybtn.onClick функцией async, а затем await вызвать update()?

Michael Platt 24.05.2019 18:13
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
1
48
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Поэтому, если вы ищете лучшие практики, я настоятельно рекомендую вам ознакомиться с обещаниями. 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.

mwilson 24.05.2019 22:24

Обновлено. Я все еще привык думать об этом с точки зрения того, когда нам нужно было иметь транспилеры для async/await.

Dude 24.05.2019 22:27
Ответ принят как подходящий

Если вы работаете с функцией, которая принимает только обратный вызов, вы можете обернуть ее внутри промиса, чтобы использовать 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();

Другие вопросы по теме