回调也称为高阶函数吗?

Is a callback also known as a higher-order function?

我正在尝试理解 回调高阶 函数,但博客 post 中有描述, Understand JavaScript Callback Functions and Use Them,这让我感到困惑,这意味着它们是同一个人:

A callback function, also known as a higher-order function,...

Quora 对 What is a simple explanation of higher order functions and callbacks in JavaScript? 问题的回答逐字重复。

这对我来说没有意义。据我了解,高阶函数接受或returns其他函数回调函数是passed/taken在中的函数,怎么会同时是呢?我对那个描述有什么不理解的地方吗?

不,回调不一定是高阶函数。他们可以。你可以有一个接受另一个函数作为参数的回调。

回调被给予给高阶函数,这可能是导致混淆的原因。一个函数接受另一个函数作为参数是导致它被归类为高阶的标准之一。

Callback function

A callback function is a function passed into another function as an argument, which is then invoked inside the outer function to complete some kind of routine or action.

Return a function

A function that returns a function called Higher-Order Function

回调函数不是高阶函数,除非它是returns函数。

简单回调:

function toto(callback){
  /** some routine or action before */
  callback();
}

function foo(){
  console.log("I'm a simple callback");
}

toto(foo);

简单的高阶函数

function toto(){
  console.log("I'm a simple Higher-Order Function")
  return function(){
     console.log("I'm the return function");
  }
}

//first log
const func = toto();
//second log
func();

也是高阶函数的回调:

function toto(callback){
  /** some routine or action before */
  const func = callback();
  func();
}

function foo(){
  console.log("I'm a callback and Higher-Order function");
  
  return function(){
    console.log("Do something...");
  };
}

toto(foo);

在我看来,高阶函数是一个接受另一个函数并使用它来抽象某些行为的函数,例如此 C# 扩展方法:

    public static IEnumerable<T> OrderByProperty<T>(this IEnumerable<T> items, Func<T, object> selector)
    {
        return items.Select(x => new { o = selector(x), item = x })
                    .OrderBy(x => x.o)
                    .Select(x=> x.item);
    }

它需要一个确定的函数,属性 在对集合进行排序时考虑该函数。 示例用法:

    var orderedByA = Enumerable.Range(0, 100)
          .Select(x=> new Item{
            A = x,
            B = 100 - x
          })
          .OrderByProperty(x => x.A);

另一方面,回调可用于在需要某些异步或长时间操作时继续应用程序流程,例如

void FirstAsync(){
    Task.Run(()=>{
        Thread.Sleep(1000);
        Console.WriteLine("First executed");
    });
}

void Second()
{
    Console.WriteLine("Second executed");
}

void FirstV2(Action callback)
{
    Task.Run(() =>
    {
        Thread.Sleep(1000);
        Console.WriteLine("First executed");
        callback?.Invoke();
    });
}

void Main()
{
    FirstAsync();
    Second();
    Thread.Sleep(2000);
    FirstV2(Second);
}

上面程序的输出如下:

Second executed
First executed
First executed
Second executed