在JavaScript中创建一个自定义回调

我所需要做的就是在当前函数执行结束时执行一个回调函数。

function LoadData()
{
alert('The data has been loaded');
//Call my callback with parameters. For example,
//callback(loadedData , currentObject);
}

这个函数的消费者应该是这样的:

object.LoadData(success);


function success(loadedData , currentObject)
{
//Todo: some action here
}

我怎么实现这个呢?

369776 次浏览

实际上,你的代码会像现在一样工作,只是把你的回调声明为一个参数,你可以直接使用参数名调用它。

最基本的

function doSomething(callback) {
// ...


// Call the callback
callback('stuff', 'goes', 'here');
}


function foo(a, b, c) {
// I'm the callback
alert(a + " " + b + " " + c);
}


doSomething(foo);

这将调用doSomethingdoSomething将调用foo,后者将提醒“东西在这里”。

注意,传递函数参考 (foo)非常重要,而不是调用函数并传递其结果(foo())。在你的问题中,你做得很好,但值得指出的是,这是一个常见的错误。

更高级的东西

有时你想调用回调函数,让它看到this的特定值。你可以用JavaScript的call函数轻松地做到这一点:

function Thing(name) {
this.name = name;
}
Thing.prototype.doSomething = function(callback) {
// Call our callback, but using our own instance as the context
callback.call(this);
}


function foo() {
alert(this.name);
}


var t = new Thing('Joe');
t.doSomething(foo);  // Alerts "Joe" via `foo`

你也可以传递参数:

function Thing(name) {
this.name = name;
}
Thing.prototype.doSomething = function(callback, salutation) {
// Call our callback, but using our own instance as the context
callback.call(this, salutation);
}


function foo(salutation) {
alert(salutation + " " + this.name);
}


var t = new Thing('Joe');
t.doSomething(foo, 'Hi');  // Alerts "Hi Joe" via `foo`

有时,将想要给回调函数的参数作为数组传递,而不是单独传递,是很有用的。你可以使用apply来做到这一点:

function Thing(name) {
this.name = name;
}
Thing.prototype.doSomething = function(callback) {
// Call our callback, but using our own instance as the context
callback.apply(this, ['Hi', 3, 2, 1]);
}


function foo(salutation, three, two, one) {
alert(salutation + " " + this.name + " - " + three + " " + two + " " + one);
}


var t = new Thing('Joe');
t.doSomething(foo);  // Alerts "Hi Joe - 3 2 1" via `foo`
function LoadData(callback)
{
alert('the data have been loaded');
callback(loadedData, currentObject);
}

试一试:

function LoadData (callback)
{
// ... Process whatever data
callback (loadedData, currentObject);
}

函数是JavaScript中的第一个类;你可以四处传阅。

在尝试执行回调函数之前,最好确保它是一个实际的函数:

if (callback && typeof(callback) === "function") {


callback();
}

我的2美分,相同但不同…

<script>
dosomething("blaha", function(){
alert("Yay just like jQuery callbacks!");
});




function dosomething(damsg, callback){
alert(damsg);
if(typeof callback == "function")
callback();
}
</script>
   function callback(e){
return e;
}
var MyClass = {
method: function(args, callback){
console.log(args);
if(typeof callback == "function")
callback();
}
}

==============================================

MyClass.method("hello",function(){
console.log("world !");
});

==============================================

结果是:

hello world !
function loadData(callback) {


//execute other requirement


if(callback && typeof callback == "function"){
callback();
}
}


loadData(function(){


//execute callback


});

当调用回调函数时,我们可以像下面这样使用它:

consumingFunction(callbackFunctionName)

例子:

// Callback function only know the action,
// but don't know what's the data.
function callbackFunction(unknown) {
console.log(unknown);
}


// This is a consuming function.
function getInfo(thenCallback) {
// When we define the function we only know the data but not
// the action. The action will be deferred until excecuting.
var info = 'I know now';
if (typeof thenCallback === 'function') {
thenCallback(info);
}
}


// Start.
getInfo(callbackFunction); // I know now

这是Codepend的完整示例。

有些答案虽然正确,但理解起来可能有点棘手。下面是一个外行术语的例子:

var users = ["Sam", "Ellie", "Bernie"];


function addUser(username, callback)
{
setTimeout(function()
{
users.push(username);
callback();
}, 200);
}


function getUsers()
{
setTimeout(function()
{
console.log(users);
}, 100);
}


addUser("Jake", getUsers);

回调意味着,“Jake”总是在显示带有console.log的用户列表之前添加到用户中。

来源(YouTube)

如果你想在某件事完成时执行一个函数。一个很好的解决方案是监听事件。 例如,我将实现一个Dispatcher,一个ES6的DispatcherEvent类,然后:

let Notification = new Dispatcher()
Notification.on('Load data success', loadSuccessCallback)


const loadSuccessCallback = (data) =>{
...
}
//trigger a event whenever you got data by
Notification.dispatch('Load data success')

调度员:

class Dispatcher{
constructor(){
this.events = {}
}


dispatch(eventName, data){
const event = this.events[eventName]
if(event){
event.fire(data)
}
}


//start listen event
on(eventName, callback){
let event = this.events[eventName]
if(!event){
event = new DispatcherEvent(eventName)
this.events[eventName] = event
}
event.registerCallback(callback)
}


//stop listen event
off(eventName, callback){
const event = this.events[eventName]
if(event){
delete this.events[eventName]
}
}
}

DispatcherEvent:

class DispatcherEvent{
constructor(eventName){
this.eventName = eventName
this.callbacks = []
}


registerCallback(callback){
this.callbacks.push(callback)
}


fire(data){
this.callbacks.forEach((callback=>{
callback(data)
}))
}
}

编码快乐!

p/s:我的代码缺少处理一些错误异常

     function login(email, password, callback) {
//verify the user
const users = [
{ email: "abc@gmail.com", password: "123" },
{ email: "xyz@gmail.com", password: "xyz" }
];


const user = users.find(
(user) => user.email === email && user.password === password
);
callback(user);
`enter code here`}


function redirect(user) {
if (user) {
//user is successfully logged in
console.log("user is successfully logged in ");
} else {
console.log("Incorrect credentials ");
}
}


    

login("abc@gmail.com", "123", redirect);

我希望这个例子能帮助所有想了解JS中回调的人