简体   繁体   English

回调函数与硬编码内部 function?

[英]Callback functions vs hardcoding inner function?

I'm reading about Callback functions in Javascript, and W3 schools reports that a callback is simply where a one function calls another, the latter of which is an argument that's passed to the first in the form of:我正在阅读 Javascript 中的回调函数, W3 学校报告说回调只是一个 function 调用另一个的地方,后者是一个参数,以以下形式传递给第一个:


const callback = () => {
    console.log('callback executed.');
};

const myFunc = (callbackFunc) => {
    console.log('myFunc started')
    callbackFunc();
};

myFunc(callback);

My question is, in practice, how is this any different than hardcoding the callback into MyFunc's definition?我的问题是,在实践中,这与将回调硬编码到 MyFunc 的定义中有什么不同? eg例如

const myFunc = () => {
    console.log('myFunc started')
    callback();
};

I've heard callback functions mentioned in the same breath as async;我听说回调函数与 async 相提并论; so my best intuition is that this design allows the exact function, to be passed as an argument to myFunc, to be decided dynamically based on some logic external to myFunc.所以我的最佳直觉是,此设计允许将确切的 function 作为参数传递给 myFunc,并根据 myFunc 外部的某些逻辑动态决定。

However, I'd like confirmation/clarification and amplifying details.但是,我想要确认/澄清和详细说明。

Your intuition is correct but the benefit and the use of it is tremendously big.您的直觉是正确的,但它的好处和用途非常大。 That's allow Separation of Concern and Dependency Inversion.这允许关注点分离和依赖倒置。

And the fact we can pass function as any other value and return value (it's what we called high-order function) allow us to process composition of it.事实上,我们可以将 function 作为任何其他值传递并返回值(这就是我们所说的高阶函数),这使我们能够处理它的组合。

Then we can code in purely functional way without the need of class to handle some state which is an Object Oriented Way.然后我们可以在不需要 class 的情况下以纯函数方式编码来处理一些 state,这是一种面向 Object 的方式。 Both paradigm can be handle in JS because it's a multi-paradigm programming language but be aware of what we do is essential to not transform the code in a entire mess.这两种范式都可以在 JS 中处理,因为它是一种多范式编程语言,但请注意我们所做的事情对于不将代码转换成一团糟至关重要。

When you will study Promise you will see how to take advantage of callback to handle side-effect in a really canny way such we can manage side-effect and push it aside to keep reasonning in a more mathematical way.当你学习 Promise 时,你会看到如何利用回调以一种非常巧妙的方式处理副作用,这样我们就可以管理副作用并将其搁置一旁,以更数学的方式进行推理。 For instance imagine:例如想象一下:

const callHttp = (callback) => {
    const res = // do asynchronuous operation taking time 
    callback(res);
};

You can dynamically pass down the result to handle it only after the delay execution to get the info.您可以动态传递结果以仅在延迟执行以获取信息后进行处理。 In such way you can program in a really neat way to manage side-effect of any types of event.通过这种方式,您可以以一种非常简洁的方式进行编程来管理任何类型事件的副作用。

Enjoy your path through Javascript;)享受您通过 Javascript 的旅程;)

Let's say we're building this web app that lets users upload images and then we can apply all sorts of image processing effects on them, like turning them into grayscale, sepia or even sharpening them.假设我们正在构建这个 web 应用程序,它允许用户上传图像,然后我们可以对它们应用各种图像处理效果,比如将它们变成灰度、棕褐色甚至锐化它们。

Initially, we thought of just creating a function called "applyEffect" that takes in the image and a string representing the desired effect.最初,我们只想创建一个名为“applyEffect”的 function,它接收图像和表示所需效果的字符串。 But, as we started adding more effects, we realized that the switch statement inside the function was becoming a nightmare to maintain.但是,当我们开始添加更多效果时,我们意识到 function 中的 switch 语句正在成为维护的噩梦。 Plus, every time we wanted to add a new effect, we had to go back and modify the "applyEffect" function.另外,每次我们想要添加新效果时,我们都必须返回 go 并修改“applyEffect”function。

 function applyEffect(img, effect) { switch (effect) { case "grayscale": applyGrayscale(img); break; case "sepia": applySepia(img); break; case "sharpen": applySharpen(img); break; // etc. } }

Now, let's try to solve it with a separate callback functions for each effect, like "applyGrayscale", "applySepia" and "applySharpness".现在,让我们尝试为每个效果使用单独的回调函数来解决它,例如“applyGrayscale”、“applySepia”和“applySharpness”。 Then, we created a new function called "applyEffect", that takes in an image and a callback function as arguments.然后,我们创建了一个名为“applyEffect”的新 function,它接受一个图像和一个回调 function 作为 arguments。

 function applyEffect(img, callback) { callback(img); }

Now, whenever we want to apply an effect to an image, we just call "applyEffect" and pass in the image, along with the appropriate callback function. It's way more flexible and easy to maintain.现在,每当我们想要对图像应用效果时,我们只需调用“applyEffect”并传入图像,以及适当的回调 function。它更加灵活且易于维护。

 applyEffect(myImage, applyGrayscale); applyEffect(myImage, applySepia); applyEffect(myImage, applySharpen);

By using callback functions, the applyEffect function is closed for modification (no need to change the applyEffect function when adding new effects) and open for extension (easily add new effects by creating new callback functions and passing them to applyEffect).通过使用回调函数,applyEffect function 关闭修改(添加新效果时无需更改applyEffect function)并打开扩展(通过创建新的回调函数并将它们传递给applyEffect 轻松添加新效果)。

This is one of the SOLID principles for writing maintainable and scalable code.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM