JavaScript: ожидание завершения функции — 5 методов, объясненных примерами кода

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

Метод 1: функции обратного вызова
Обратные вызовы — это традиционный и широко используемый подход для обработки асинхронных задач в JavaScript. Вы можете передать функцию обратного вызова в качестве параметра функции, которую хотите дождаться, и вызвать обратный вызов после завершения задачи. Вот пример:

function longRunningTask(callback) {
  // Simulate a time-consuming task
  setTimeout(() => {
    console.log("Task completed!");
    callback();
  }, 3000);
}
function handleTaskCompletion() {
  console.log("Continuing after task completion...");
}
longRunningTask(handleTaskCompletion);

Метод 2: обещания
Обещания предоставляют более элегантный и читаемый способ обработки асинхронного кода. Вы можете обернуть функцию, которую хотите дождаться, в промис и выполнить ее после завершения задачи. Вот пример:

function longRunningTask() {
  return new Promise((resolve, reject) => {
    // Simulate a time-consuming task
    setTimeout(() => {
      console.log("Task completed!");
      resolve();
    }, 3000);
  });
}
longRunningTask().then(() => {
  console.log("Continuing after task completion...");
});

Метод 3: Async/Await
Появленный в ES2017, метод async/await обеспечивает более чистый синтаксис для написания асинхронного кода. Вы можете пометить функцию, содержащую асинхронную задачу, ключевым словом asyncи использовать ключевое слово await, чтобы дождаться ее завершения. Вот пример:

async function longRunningTask() {
  // Simulate a time-consuming task
  await new Promise(resolve => setTimeout(resolve, 3000));
  console.log("Task completed!");
}
async function handleTask() {
  await longRunningTask();
  console.log("Continuing after task completion...");
}
handleTask();

Метод 4: Программирование, управляемое событиями
В некоторых случаях вы можете использовать программирование, управляемое событиями, чтобы дождаться завершения функции. Этот подход предполагает запуск события после завершения функции и подключение к этому событию прослушивателя для выполнения желаемого кода. Вот пример использования класса EventEmitterиз Node.js:

const EventEmitter = require('events');
function longRunningTask() {
  const emitter = new EventEmitter();
  // Simulate a time-consuming task
  setTimeout(() => {
    console.log("Task completed!");
    emitter.emit('taskCompleted');
  }, 3000);
  return emitter;
}
const taskEmitter = longRunningTask();
taskEmitter.on('taskCompleted', () => {
  console.log("Continuing after task completion...");
});

Метод 5: ожидание при занятости (не рекомендуется)
Ожидание при занятости включает в себя повторную проверку состояния до тех пор, пока функция не завершится. Этот метод обычно не рекомендуется, поскольку во время ожидания он потребляет ресурсы ЦП. Однако в определенных сценариях это может быть единственный доступный вариант. Вот пример:

function longRunningTask() {
  // Simulate a time-consuming task
  setTimeout(() => {
    console.log("Task completed!");
  }, 3000);
}
function waitUntilTaskCompletes() {
  return new Promise(resolve => {
    const checkInterval = setInterval(() => {
      if (/* condition to check if task completed */) {
        clearInterval(checkInterval);
        resolve();
      }
    }, 100);
  });
}
async function handleTask() {
  longRunningTask();
  await waitUntilTaskCompletes();
  console.log("Continuing after task completion...");
}
handleTask();

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