Как реагировать на функцию, которая устанавливает тайм-аут

#javascript #async.js

#javascript #async.js

Вопрос:

У меня есть функция:

 function a(){ setTimeout(()=>{console.log('a')}, 0) }
 

Эта функция отправляет консоль.войдите в систему в самом конце callstack, не так ли?

Как я могу написать функцию, которая запускается после этого console.log

единственный способ, который я нашел, — это отправить функцию в из стека вызовов таким же образом

 a();
setTimeout(()=>{ console.log('after a'), 0 });
 

Но для меня это выглядит плохо. Я пробовал с обещанием, но тогда я могу реагировать на функцию «a» не на консоли.войдите внутрь.

функция ‘a’ не редактируется

Комментарии:

1. Сделайте так, чтобы принять обратный вызов и вызвать его в нужное время: function a(callback){ setTimeout(()=>{console.log('a'); callback?.()}, 0) } , затем a(() => console.log('after a')); .

2. В качестве альтернативы с помощью Promise: function a(){ return new Promise( resolve => setTimeout(()=>{console.log('a'); resolve()}, 0) ) } , затем используйте его как a().then(() => console.log('after a')) .

3. функция ‘a’ не редактируется

Ответ №1:

вы можете использовать «обратный вызов» , ссылку на другую функцию для функции a( ) . Пример:

 function yourFunctionToBeRunnedAfter(){
..
..
}

function a(callback){ 
   setTimeout(()=>{
         console.log('a');
         calback();  // ==> here is your function execution.
    }, 0);
}

a(yourFunctionToBeRunnedAfter);
 

если у вас есть параметры для передачи в вызов обратного вызова (), вы можете использовать apply() или call() или bind() или оператор распространения (…) пример:

 function a(callback,...params){  // ... is the spread operator
   setTimeout(()=>{
         console.log('a');
         callback([...params]);  // ==> here is your function execution by spreading your params to the callback call.
    }, 0);
}
a(yourFunctionToBeRunnedAfter, 1,2,3);
 

Комментарии:

1. в javascript вы можете переопределить любой объект (функция — это объект), используя прототипирование или даже без него (в вашем случае), пример: a = function(обратный вызов){ .. .. }

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

3. если бы я был на вашем месте, и функция недоступна для редактирования, я бы использовал некоторые приемы, чтобы скопировать содержимое / логику ссылки на функцию в другую спроецированную ссылку и правильно ее обработать. Я не думаю, что есть другое решение, если вы не используете обратные вызовы, обещания, наблюдаемые или даже объект » прокси «, который может быть полезен в вашем случае. Но, честно говоря, нам все еще нужно больше информации о том, что вам нужно..

4. Я понимаю. Это часть интервьюирования задания. Я не могу так «обманывать». Но я не могу найти другого решения, кроме как сделать еще один тайм-аут, чтобы поместить другую функцию в конец в callstack. Но это кажется простым и неэлегантным. Мне интересно, есть ли лучшее решение

Ответ №2:

Вам нужно использовать обещание. Я бы рекомендовал использовать async-await, но это действительно зависит от ваших предпочтений.

 function a () {
  return new Promise(resolve => {
    setTimeout(() => {
      console.log('a')
      resolve()
    }, 0)
  })
}

a().then(() => console.log('after a'))
 

Если вам нужно знать, когда часто заканчиваются тайм-ауты, я бы рекомендовал создать вспомогательную функцию:

 const wait = (time) => new Promise(r => setTimeout(r, time))
 

Затем вы можете использовать его следующим образом:

 (async () => {
  console.log('Hello')
  await wait(1000) // wait 1 second
  console.log('Hello a second later')
})()