Асинхронный код с коллбэками в JavaScript

Пусть у нас есть некоторая асинхронная функция:

javascriptfunction make() {
  setTimeout(function() {
    console.log('1');
  }, 3000);
}

Пусть мы используем эту функцию следующим образом:

javascriptmake();
console.log('2'); // выполнится первым

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

javascriptmake(function() {
  console.log('2');
});

Конечно же, само по себе это не решит нашу задачу. Пока мы просто заключили следующее соглашение: при желании выполнить код после срабатывания make передайте этот код коллбэком в вызов make.

Исправим код функции make так, чтобы она начала работать в соответствии с нашим соглашением:

javascriptfunction make(callback) {
  setTimeout(function() {
    console.log('1'); // некая асинхронная операция, может не одна
    callback();       // затем наш коллбэк
  }, 3000);
}
Задание 1

Расскажите, в каком порядке выведутся числа в консоль:

javascriptfunction make(callback) {
  setTimeout(function() {
    console.log('1');
    callback();
  }, 3000);
}

make(function() {
  console.log('2');
  console.log('3');
});