Я изучаю javascript и переписал этот код из книги:

var controller = {};
controller.queue=[];
controller.add = function (func) {
                  controller.queue.push(func);
                 };
controller.run = function () {
                  controller.queue.shift() (controller.run);
                  
                 }

function longRunA(callback){
  console.log("A");
  setTimeout(callback,2000);
}
function longRunB(callback){
  console.log("B");
  setTimeout(callback,1000);
}

controller.add(longRunA);
controller.add(longRunB);
controller.run();

Распечатка верна, A через две секунды после B, это то, что он должен был сделать.

Некоторые вещи мне непонятны.

  1. Почему он пишет controller.run в скобках после вызова controller.queue.shift ()? Я не понимаю, сделано ли это для рекурсивной функции, и я не понимаю роль круглых скобок, окружающих controller.run. Консоль сообщает об этой проблеме: uncaught typeerror: controller.queue.shift (..) is not a function at controller.run
  2. controller.add вызывается с аргументом longRunA, но я не понимаю, почему правильно вызывать функцию longRunA без аргументов. Я бы убрал слово обратный вызов в определении функции.
2
Antilope 11 Фев 2021 в 14:54

3 ответа

Лучший ответ

Функции в Javascript могут быть:

  • передается другим функциям в качестве аргументов
  • возвращается изнутри другой функции
  • сохраняется внутри структуры данных, такой как массив
  • присвоено переменным

Дополнительные сведения см. На странице MDN - First-Class Function


Переходя к различным вопросам, которые у вас есть относительно рассматриваемого кода.

почему он пишет в скобках controller.run после вызова controller.queue.shift ()

Если controller.queue.shift() возвращает функцию, вы можете вызвать ее, добавив после нее скобки, и, как и любую другую функцию, вы можете передать ей аргументы. В этом случае controller.run передается в качестве аргумента функции, возвращаемой controller.queue.shift()

В следующем фрагменте кода показан пример:

function sayHi(name) {
  console.log("Hi " + name + "!");
}

const arr = [sayHi];

arr.shift()("John");

В приведенном выше фрагменте кода arr.shift() возвращает функцию sayHi, которую мы затем вызываем с помощью круглой скобки () и передаем «Джон» в качестве аргумента.

Консоль сообщает об этой проблеме: uncaught typeerror: controller.queue.shift (..) не является функцией в controller.run

Вы получаете эту ошибку, потому что внутри функции longRunB вы вызываете функцию callback, то есть controller.run, но когда эта функция вызывается, она пытается получить первый элемент массива controller.queue но на данный момент он пуст.

Один из способов решить эту проблему - убедиться, что controller.queue.shift() дает вам функцию, прежде чем пытаться ее вызвать.

controller.add вызывается с аргументом longRunA, но я не понимаю, почему правильно вызывать функцию longRunA без аргументов

controller.add - это функция, которой longRunA передается в качестве аргумента. longRunA здесь не вызывают.

1
Yousaf 11 Фев 2021 в 13:38

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

function longRunB (callback) {
   console.log ("B");
   // setTimeout (callback, 1000);
} 
0
Antilope 11 Фев 2021 в 13:15

Для предотвращения ошибки вы можете использовать цикл while.

var controller = {};
controller.queue=[];
controller.add = function (func) {
                  controller.queue.push(func);
                 };
controller.run = function () {
                  while ( controller.queue.length > 0) {
                         controller.queue.shift()(controller.run);
                      }
                  } 
                  

function longRunA(callback){
  console.log("A");
  setTimeout(callback,2000);
}
function longRunB(callback){
  console.log("B");
  setInterval(callback,1000);
}

controller.add(longRunA);
controller.add(longRunB);
controller.run();
-1
hamed 11 Фев 2021 в 13:06
66154269