Как работает setTimeout на узле.JS, пожалуйста, объясните этот фрагмент кода

#javascript #settimeout

#javascript #settimeout

Вопрос:

Я как раз готовился поработать с Nodejs, но, экспериментируя и немного играя с первым примером, я обнаружил некоторое поведение, которое мне трудно понять.

 var a = function () {
    console.log('print 3');
    return 5000;
    };

setTimeout( function (){
   console.log('print 2');
   }, a()
);

console.log('print 1');
  

Вывод к приведенному выше коду является:

печать 3 
печать 1 
печать 2

И глупое сомнение заключается в том, что, хотя приведенный выше код работает, этот — нет.

 setTimeout( function (){
   console.log('print 2');
   }, (function () {console.log('print 3'); return 5000;} )
);
console.log('print 1');
  

Пожалуйста, объясните описанное выше поведение.

Ответ №1:

Лучшее форматирование кода должно помочь вам понять, что происходит.

 var a = function () {
  console.log('print 3');
  return 5000;
};

setTimeout( function (){
  console.log('print 2'); # Executed after 5000 ms.
  },
a());                    # Executed first and returns 5000

console.log('print 1');  #Executed second
  

Следующий фрагмент не работает, так как вы никогда не выполняете 2-ю часть функции.

 setTimeout( function (){
  console.log('print 2');
  }, (function () {            # Never executed.
    console.log('print 3');
    return 5000;
  } )
);

console.log('print 1'); 
  

Будет работать следующее:

 setTimeout( function (){
  console.log('print 2');
  }, (function () {            
    console.log('print 3');
    return 5000;
  } )();                      #The brackets () will execute the function.
);

console.log('print 1'); 
  

В качестве отступления

Пример не имеет ничего общего с node.js и выдаст точно такие же результаты в любом браузере, который отвечает на консоль.

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

1. Спасибо Газлеру за такое красивое объяснение.

Ответ №2:

setTimeout принимает два аргумента (по крайней мере, так, как вы его используете).

Первый аргумент — это вызываемая функция, а второй аргумент — время задержки перед ее вызовом.

В вашем первом примере вы передаете анонимную функцию и число (возвращаемое значение a() ).

Во втором примере вы передаете две анонимные функции (потому что вы никогда не вызываете вторую функцию (ее нет () )).

 setTimeout( 
    function (){
        console.log('print 2');
    },
    (function () {console.log('print 3'); return 5000;})()
);
console.log('print 1');
  

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

1. Спасибо Квентину за такое красивое объяснение

Ответ №3:

Вам нужно вызвать 2-й параметр — setTimeout ожидает число

 setTimeout( function (){
   console.log('print 2');
   }, (function () {console.log('print 3'); return 5000;} )()
);
console.log('print 1');