首页 > 解决方案 > 当我可以简单地调用回调函数时,为什么要使用它们?

问题描述

我在这里阅读了回调函数(也在我参与的在线课程中),现在我被卡住了。原因是我无法理解如果我可以简单地调用它们,为什么我需要使用回调函数。以下示例:

1 - 使用回调函数:

    function showArticle(id, callbackSuccess, callbackError){
        
        if (true){
            callbackSuccess("This is a callback function", "It is very utilized.");
        } else {
            callbackError("Error on data recovery.");
        }

    }

    var callbackSuccess = function(title, description){
        document.write("<h1>" + title + "</h1>");
        document.write("<hr>");
        document.write("<p>" + description + "</p>");
    }

    var callbackError = function(error){
        document.write("<p><b>Erro:</b>" + error + "</p>");
    }

    showArticle(1, callbackSuccess, callbackError);

2 - 这是我的代码不使用回调函数并具有相同的结果:

    function showArticle(id){
        
        if (true){
            callbackSuccess("This is a callback function", "It is very utilized.");
        } else {
            callbackError("Error on data recovery.");
        }

    }

    var callbackSuccess = function(title, description){
        document.write("<h1>" + title + "</h1>");
        document.write("<hr>");
        document.write("<p>" + description + "</p>");
    }

    var callbackError = function(error){
        document.write("<p><b>Erro:</b>" + error + "</p>");
    }

    showArticle(1);

为什么我应该使用回调函数而不是在示例 2 中简单地调用它们?

标签: javascript

解决方案


没错,在您给出的示例中,回调函数没有意义,但这不是通常使用回调函数的方式。

通常,使用回调:

  1. 通过为数组、列表或其他容器中的每个元素调用回调的迭代、映射或过滤函数

  2. 通过执行异步工作的函数,在工作成功完成、失败或两者兼有时调用您的回调(取决于您调用的 API 的样式)

  3. 通过接受回调的函数,它们会在发生某些事情时调用,例如clickDOM 元素上的事件处理程序

...但也有其他类别。

数组上的filter函数是 #1 的示例:它为数组中的每个条目调用回调,使用回调的返回值来决定条目是否应该在它返回的新过滤数组中:

const numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
const odds = numbers.filter(num => {
    console.log(`callback called with ${num}`); // logs 10 times
    return num % 2;
});
console.log(odds); // [1, 3, 5, 7, 9]

Promise 方法thencatchfinally是#2 的示例。假设我们有一个startSomethingAsynchronous返回 Promise 的函数。以下是如何设置履行和拒绝处理程序(回调):

startSomethingAsynchronous()                // Starts an asynchronous process
.then(result => {                           // <−+
    // ...do something with the result...   //   +− This is a fulfillment handler
})                                          // <−+
.catch(error => {                           // <−+
    // ...report or handle error...         //   +− This is a rejection handler
});                                         // <−+

如果 promise fromstartSomethingAsynchronous()被履行(成功完成),则调用履行处理程序。如果该承诺被拒绝(失败),或者如果该承诺已履行但then拒绝返回的承诺(例如,因为履行处理程序中发生错误),则调用拒绝处理程序。(像这样链接事情是相当普遍的,但是还有很多其他的方式来使用 Promise,这只是一个例子。)

DOM 中的addEventListener函数是#3 的示例:

document.querySelector("input[type=button]")
    .addEventListener("click", function() {
        console.log("Clicked!"); // logs as many times as you click the button
    });
<input type="button" value="Click Me">


推荐阅读