javascript顺序回调练习

javascript exercise of sequential callback

我正在学习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.queue.shift ()后括号里写controller.run?不明白是不是为了让函数递归,也不明白controller.run两边的圆括号的作用。控制台报告此问题:uncaught typeerror: controller.queue.shift (..) is not a function at controller.run
  2. controller.add 是用 longRunA 参数调用的,但我不明白为什么不带参数调用 longRunA 函数是正确的。我会在函数定义中删除回调这个词。

Javascript 中的函数可以是:

  • 作为参数传递给其他函数
  • 从另一个函数内部返回
  • 保存在数组等数据结构中
  • 分配给变量

详情请见:MDN - First-Class Function


关于您对相关代码的不同问题。

why does he write controller.run in parentheses after calling controller.queue.shift ()

如果 controller.queue.shift() returns 是一个函数,那么您可以通过在它后面添加括号来调用它,就像任何其他函数一样,您可以向它传递参数。在这种情况下,controller.run 作为参数传递给 controller.queue.shift()

返回的函数

以下代码片段显示了一个示例:

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

const arr = [sayHi];

arr.shift()("John");

在上面的代码片段中,arr.shift() returns 然后我们使用括号 () 调用 sayHi 函数并将“John”作为参数传递。

The console reports this problem: uncaught typeerror: controller.queue.shift (..) is not a function at controller.run

你得到这个错误是因为在 longRunB 函数中,你调用了 callback 函数,即 controller.run 但是当调用该函数时,它试图获取 callback 的第一个元素=21=] 数组,但此时它是空的。

解决此问题的一种方法是确保 controller.queue.shift() 在尝试调用之前为您提供了一个函数。

controller.add is called with longRunA argument, but I don't understand why it is correct to call longRunA function without arguments

controller.add 是一个函数,longRunA 作为参数传递给该函数。 longRunA 未在此处调用。

为了防止错误,您可以使用 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();

好的,感谢您的回答,我明白了错误。最后调用的回调函数要注释掉,因为没有更多的函数了:

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