Функция обратного вызова Javascript не выполняется должным образом - PullRequest
0 голосов
/ 25 декабря 2018

Согласно этому стеку потока ответ ,

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

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

function myfun(a, b, callback) {
    console.log(a);
    callback();
    console.log(b);
}

function cb() {console.log('hi')}

myfun(1, 2, cb)   // result: 1 hi 2

результат не 1 2 hi, как я ожидал, из чего я делаю вывод, что только функции обратного вызова, которые запускают некоторый «сигнал события», такой как setTimeout, будут помещены в такую ​​очередь, но я не могу найти конкретную ссылку для поддержки?

Ответы [ 2 ]

0 голосов
/ 25 декабря 2018

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

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

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

function myfun(a, b, callback) {
  console.log(a);
  callback();
  console.log(b);
}

function cb() {
  console.log('hi')
}

myfun(1, 2, cb) // result: 1 hi 2

// same behavior as above

function myStaticFun() {
  console.log(1);
  cb();
  console.log(2);
}

myStaticFun();

// now same as before using a promise to wait a moment and the event loop stack is invoked during the pause

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function myEventLoopInvokingFun(a, b, callback) {
  console.log(a);
  setTimeout(callback, 0)
  await sleep(0);
  console.log(b);
}

myEventLoopInvokingFun(1, 2, cb);
0 голосов
/ 25 декабря 2018

Это не обязательно означает, что каждый callback равен asynchronous и должен быть помещен в некоторую task queue и выполняться после завершения synchronous фрагментов кода (стек вызовов пуст) завершается.Функции обратного вызова, имеющие дело с Promise s, являются кандидатами на task queue.Например, в вашем случае;cb функция просто запускается синхронно;так что результат будет 1 hi 2 как вы указали;однако если мы изменим ваш код следующим образом:

function myfun(a, b, callback) {
    console.log(a);
    window.setTimeout(callback, 0);
    console.log(b);
}

function cb() {
    console.log('hi');
}

myfun(1, 2, cb)   // result: 1 2 hi

, это приведет к 1 2 hi.Несмотря на то, что я установил таймаут на 0 миллисекунды;Функция cb будет выводиться после второй console.log в функции myfun.Я бы порекомендовал вам взглянуть на MDN и это хорошее объяснение стека вызовов, цикла событий и очередей задач.Надеюсь, это поможет.

...