Javascript: что такое обратный вызов? - PullRequest
0 голосов
/ 22 января 2019

В этой статье , на которую я ссылался, делается следующее утверждение:

Обратные вызовы - это способ убедиться, что определенный код не выполняется, пока другой код уже не былзаконченное исполнение.

Далее статья иллюстрирует это примером:

function doHomework(subject, callback) {
  alert(`Starting my ${subject} homework.`);
  callback();
}

doHomework('math', function() {
  alert('Finished my homework');

После этого в статьях говорится:

Как выВы увидите, что если вы введете приведенный выше код в консоль, вы получите два предупреждения спина к спине: предупреждение «начало домашней работы», а затем предупреждение «готовая домашняя работа».

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

function doHomework(subject, callback) {

  setTimeout(function(){
      console.log(`Starting my ${subject} homework.`);
  }, 500); 

  callback();
}

doHomework('math', function() {
  console.log('Finished my homework');
});

В результате я получаю:

steve@Dell ~/my-app $ node app.js 
Finished my homework
Starting my math homework.
});

Я использую здесь узел (следовательно, console.log () заменяет alert ()), но я делаюне думаю, что это уместно.

Мне кажется, что я упустил что-то совершенно фундаментальное и мне нужно попытаться получить доступ к тому, что я пытаюсь понять, прежде чем я попытаюсь понять это.

Любая помощь в этом путешествии будет принята с благодарностью.

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

function first(){
  // Simulate a code delay
  setTimeout( function(){
    console.log(1);
  }, 500 );
}

function second(){
  console.log(2);
}

first();
second();

Выше в консоли возвращается 2, а затем 1.

Я пытался (безуспешно) изменить порядок возврата на 1, а затем 2 с помощью этого:

function first(callback){
    setTimeout(function(){
        console.log(1);
    }, 500);
    callback();
}
function second(){
    console.log(2);
}
first(second);

Ответ, который я получил от Cleared (до того, как он был отредактирован), заключался в том, чтобы поместить callback () в функцию setTimeout ().Он использовал пример домашней работы, но вот с этим примером:

function first(callback){
    setTimeout(function(){
        console.log(1);
        callback();
    }, 500);
}

function second(){
    console.log(2);
}

first(second);

Я думаю, что это ближе к тому, к чему я представлял статью.Кажется, это имеет смысл, хотя я предполагаю, что точный контекст того, что вы делаете, и того, что вы хотите сделать, определяет, что правильно или неправильно.

Ответы [ 4 ]

0 голосов
/ 22 января 2019

Что такое обратный вызов?

Обратный вызов означает функцию-функцию-рекурсивную функцию.

Позвольте привести пример:

Каждый день мы едим, а потом спим.Но в коде JS JS is an impatient language в отличие от PHP.Вот пример кода:

// Consuming 3s to eating(just an example, not really 3s)
function eating() {
    setTimeout(function() {
        console.log('Eating...');
    }, 3000);
}

// Then go to sleep
function sleep() {
    console.log('Z..Z..Z');
}

eating();
sleep();

Но вы спите сразу после ... (Когда мы запускаем код, сначала запускается сон, а затем есть ())

Чтобы убедиться, что все работаетв порядке, то есть вы ложитесь спать только когда закончили есть.Поэтому нам нужно, чтобы eating() сообщил, когда это будет сделано, чтобы запустить sleep():

// Consuming 3s to eating(just an example, not really 3s)
function eating(callback) {
    setTimeout(function() {
        console.log('Eating...');
        callback() // the function which will be proceeded after "Eating..."
    }, 3000);
}

// Then go to sleep
function sleep() {
    console.log('Z..Z..Z');
}

// call the function
eating(function() {
    sleep();
});

Да!Прямо сейчас я думаю, что вы можете использовать обратный вызов в вашем коде!

Где вы можете увидеть обратный вызов?

Вы можете увидеть его в каждом JQuery коде:

$("#hide").click(function(){ //the click() function call the function inside it which is callback
  $("p").hide();
});

$("#show").click(function(){
  $("p").show();
});
0 голосов
/ 22 января 2019

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

Так что, если я понимаю ваш вопрос, функция doHomework должна начать делать домашнюю работу (которая занимает время, в данном случае 500 мс), и тогда домашняя работа закончена. Таким образом, важных вещей в вашем случае - это console.log('Starting my ${subject} homework.');, который «занимает 500 мс» (поскольку это время, которое вам нужно для выполнения домашней работы).

Следовательно, вы должны поместить вызов в функцию обратного вызова сразу после console.log('Starting my ${subject} homework.');, т.е.

function doHomework(subject, callback) {

  setTimeout(function(){
      console.log(`Starting my ${subject} homework.`);
      callback();
  }, 500); 
}

doHomework('math', function() {
  console.log('Finished my homework');
});
0 голосов
/ 22 января 2019

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

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

Итак, чтобы гарантировать, что ваш код будет работать после завершения необходимой логики, вы должны передать функцию обратного вызова, которая выполняется, когда выполняется требуемое состояние (т. Е. Успех / ошибка при загрузке задач или тайм-аут «закончен» ».

Пример домашней работы IMO не лучший образец, потому что он не касается реальных случаев использования, поскольку он всегда «ждет» 500 мс.

В вашем примере проблема в том, что ваш «обратный вызов» находится вне «асинхронной» части кода, поэтому он выполняется сразу после запуска тайм-аута, даже если тайм-аут все еще «работает». Может быть, вы думаете о SetTimeout, это проблема, в моих начинаниях javascript я думал, что это больше похоже на «паузу на 500 мс», но это «выполнение кода с заданной областью после ожидания 500 мс из нормального потока кода»

Вот еще некоторые сведения, я могу порекомендовать всю страницу, даже если вы не javascript noob;) https://javascript.info/callbacks

0 голосов
/ 22 января 2019

Как правило, вы вызываете функцию обратного вызова, когда вы закончили , делая то, что вы делаете.

Таким образом, у вас есть код внутри и снаружи функции setTimeout в обратном направлении.

function doHomework(subject, callback) {
    console.log(`Starting my ${subject} homework.`);
    setTimeout(function(){
        console.log(`Finished my ${subject} homework.`);
        callback();
    }, 500); 
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...