Я изучаю 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, это то, что он должен был сделать.
Некоторые вещи мне непонятны.
- Почему он пишет
controller.run
в скобках после вызоваcontroller.queue.shift ()
? Я не понимаю, сделано ли это для рекурсивной функции, и я не понимаю роль круглых скобок, окружающихcontroller.run
. Консоль сообщает об этой проблеме:uncaught typeerror: controller.queue.shift (..) is not a function at controller.run
controller.add
вызывается с аргументомlongRunA
, но я не понимаю, почему правильно вызывать функциюlongRunA
без аргументов. Я бы убрал слово обратный вызов в определении функции.
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
здесь не вызывают.
Хорошо, благодаря вашим ответам я понял ошибку. Последний вызов функции обратного вызова нужно закомментировать, потому что функций больше нет:
function longRunB (callback) {
console.log ("B");
// setTimeout (callback, 1000);
}
Для предотвращения ошибки вы можете использовать цикл 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();
Похожие вопросы
Новые вопросы
javascript
По вопросам программирования на ECMAScript (JavaScript / JS) и его различных диалектах / реализациях (кроме ActionScript). Включите все соответствующие теги в свой вопрос; например, [node.js], [jquery], [json] и т. д.