Mon application Vue utilise un objet JS simple pour centraliser les appels de base de données. Je veux consoler le journal des appels. À cette fin, je décore les méthodes de l'objet, comme illustré ci-dessous :

const Caller = {
    callingDB (arg1, arg2) { return ... } //Promise-wrapped db call here
}
const decorator = f => (...args) => {
    return f(...args).then(res => console.log(`Invoked method ${f.name} with ${args} for result: ${res}`))
}

Caller.callingDB = decorator(Caller.callingDB)

Et dans plusieurs composants Vue, j'ai des méthodes de composant appelant la méthode d'objet simple susmentionnée comme: ...

methods: {
 cMethod() { this.Caller.callingDB(arg1, arg2) }
}

Il y a cependant une mise en garde : une fois décorée, la méthode Caller.callingDB génère une erreur en raison du fait que « ceci » n'est pas défini - le flux de données dans mon application repose ici et là sur des appels de base de données enchaînés via des méthodes comme celle illustrée ci-dessus, qui sont invoqués de la même manière. Tout fonctionne bien sans décoration.

Je ne comprends pas pourquoi ces erreurs se produisent. Un indice sur la façon dont je devrais réécrire mon décorateur pour préserver toutes les invocations ultérieures liées à cette limite ? Ou ai-je raté le coupable derrière ces erreurs ?

1
MrNycticorax 16 mars 2019 à 23:21

2 réponses

Meilleure réponse
const decorator = f => (...args) => {
    return f.apply(Caller, args).then(res => console.log(`Invoked method ${f.name} with ${args} for result: ${res}`))
}

Les fonctions dans js ont la méthode apply qui prend une valeur this comme premier argument et le tableau d'arguments comme deuxième argument.

Voici un violon du code modifié en action https://jsfiddle.net/435h2gwp/

1
chris.va.rao 16 mars 2019 à 20:38

Pour étendre la réponse de @chris.va.rao :

Sans avoir besoin de coder en dur l'objet "Caller":

const Caller = {
        foo() {
        return new Promise((resolve) => {
        setTimeout(() => {
            this.counter = this.counter || 1;
          resolve(this.counter);
        }, 1000);
      });
    },
    callingDB(arg1, arg2) {
      return this.foo();
    } //Promise-wrapped db call here
}
function decorator (f) {

    return (...args) => f.apply(this,[...args])
    .then(res => console.log(`Invoked method ${f.name} with ${args} for result: ${res}`))
}


Caller.callingDB = decorator.bind(Caller)(Caller.callingDB);

Caller.callingDB(1, 2, 3);

violon

1
Estradiaz 16 mars 2019 à 21:40