Ich baue eine Middleware-Schicht zwischen meinen Socket.IO-Ereignissen und dem Rest meiner Anwendung. Ich tue das, damit ich Socket.IO für etwas anderes in der Zukunft austauschen kann.Wie zwei Funktionen verglichen werden, die mit `.bind()` aufgerufen werden?
Ich speichere Callback-Funktionen in einem Array. Wenn ein bestimmtes Ereignis ausgelöst wird, gehe ich über das Array und führe die Callback-Funktionen aus. Das funktioniert wie ein Zauber.
Das Problem liegt in der Entfernung eines Rückrufs von diesem Array. Wenn eine Callback-Funktion entfernt werden muss, führe ich eine Schleife über das Array und überprüfe jedes Array-Element, um zu sehen, ob es gleich ist (unter Verwendung von ===
) mit dem Callback, den ich entfernen möchte. Wenn nur der Rückruf im Array gespeichert wird, funktioniert das problemlos. Wenn jedoch ein Rückruf in Kombination mit .bind()
gespeichert wird, gibt die Gleichheitsüberprüfung false zurück.
Ich habe einen (vereinfachten) Codepen erstellt, um das Problem zu demonstrieren: http://codepen.io/petergoes/pen/wWPJdg?editors=0012.
Ich ziehe Inspiration aus dem Socket.IO-Code, um meine Entfernungsmethode zu schreiben: https://github.com/socketio/socket.io-client/blob/master/socket.io.js#L1623. Dort tritt jedoch das gleiche Problem auf.
Die große Frage:
Wie kann ich vergleichen zwei Funktionen, wenn (eine oder beide) mit der .bind()
Methode aufgerufen?
Ich fand diese Antwort how do I compare 2 functions in javascript. Allerdings fühlt sich die String-Version einer Funktion vergleicht ein wenig lückenhaft
Die codepen Referenz:
var callbackList = [];
var objA = {
myCallbackFunction: function myCallbackFunction() {
console.log('hello my name is:', this.myName);
}
}
var objB = {
register: function register(callback) {
console.log('register callback');
callbackList.push(callback);
},
remove: function remove(callback) {
console.log('remove callback');
if(callbackList[0] === callback) {
console.log('callback found, splice it');
callbackList.splice(0, 1);
} else {
console.log('callback NOT found!');
}
console.log('callbackList length:', callbackList.length);
}
}
objB.register(objA.myCallbackFunction.bind({myName: 'Peter'}));
objB.remove(objA.myCallbackFunction.bind({myName: 'Peter'}));
console.log('\nreset callbackList\n');
callbackList = [];
objB.register(objA.myCallbackFunction);
objB.remove(objA.myCallbackFunction);
Ich denke, das funktioniert nicht mit 'bind' (außer mit jedem Hack wahrscheinlich). Sie sollten sich sowieso nicht auf Funktionsidentitäten oder Funktionsnamen verlassen. Diese Art von Metaprogrammierung führt (meiner Meinung nach) zu schlechtem Code. – ftor
@ LUH3417 Was meinen Sie mit Funktionsidentitäten? –
Gegeben ist 'const f = x => x + 1, g = x => x + 1' als der folgende Ausdruck vergleicht die Identität der Funktionsobjekte 'f === g', was 'falsch' ergibt. Daher sind sie gleich, aber nicht identisch. – ftor