Callback: quando restituire il valore e quando modificare il parametro?

3

Durante la scrittura di una richiamata, quando è meglio che il callback restituisca un valore, e quando è meglio che il callback modifichi un parametro? C'è una differenza?

Ad esempio, se volessimo prendere una lista di dipendenze, quando faresti questo:

function GetDependencies(){
    return [{"Dep1" : 1.1}, 
            {"Dept2": 1.2}, 
            {"Dep3" : 1.3}];
}

E quando lo faresti?

function RegisterDependencies(register){
    register.add("Dep1", 1.1);
    register.add("Dep2", 1.2);
    register.add("Dep3", 1.3);
}
    
posta Code Slinger 03.06.2014 - 17:46
fonte

4 risposte

2

Poiché il tuo esempio utilizza un linguaggio simile a JavaScript (digitato a forma di anatra), la mia risposta sarà specifica per le lingue con dattilografia.

Da un punto di vista dell'usabilità, i parametri sono un po 'più autodocumentanti, quindi restituiscono valori. Se qualcuno stava eseguendo la scansione del codice e ha visto:

function callback( model, rootElement )
{
    //TODO: implement editor UI
}

È un po 'più ovvio ciò che dovrebbe essere fatto allora:

function callback( model )
{
    //TODO: implement editor UI
    // ... okay, where?
}

Inoltre, i programmatori curiosi hanno un po 'più di lavoro con i parametri forniti. Ad esempio, immagina un oggetto Opzioni con 20 opzioni configurabili. Fornendo che l'oggetto Options come parametro (precaricato con valori predefiniti) dia al programmatore la possibilità di penetrare nell'oggetto ed esplorare un po ':

function callback( options )
{
    console.log( options );
}

Mentre un callback che deve restituire un oggetto opzioni richiede che il programmatore trovi la documentazione:

function callback()
{
    // umm... return what?
}

Inoltre, se vuoi che venga restituito un valore ma l'utente non restituisca un valore, cosa succede? Ho visto molti casi in cui questa condizione ha prodotto errori "non può leggere la proprietà di non definito" ... che di solito interrompe la pagina.

Se all'utente viene assegnato un parametro e gli viene dato il permesso di modificarlo, non dipenderai dal fatto che stiano facendo qualcosa. Ad esempio, forse l'utente vuole solo registrare che qualcosa è successo e il tuo callback è un posto conveniente per farlo. Richiedere che restituiscano qualcosa rende il codice più complicato.

function setOptionsCallback( options )
{
    console.log( 'object created' );
}

Versus:

function setOptionsCallback()
{
    console.log( 'object created' );
    return {};
}

Alla fine, però, la maggior parte di questi problemi può essere superata con una buona programmazione difensiva e una solida documentazione.

    
risposta data 03.06.2014 - 18:42
fonte
2

Le richiamate rientrano nelle seguenti categorie generali:

  1. Quelli che producono un effetto collaterale ma il meccanismo di invio non si preoccupa degli effetti collaterali. Di solito non restituiscono nulla. Tutto ciò di cui hanno bisogno per funzionare correttamente sono forniti attraverso argomenti alla funzione. Ciò potrebbe comportare anche la modifica del contenuto degli argomenti.

  2. Quelli che possono o meno produrre un effetto collaterale, ma il meccanismo di spedizione si preoccupa se ci sono riusciti o meno. Queste funzioni in genere restituiscono un numero intero che indica lo stato dell'esecuzione della funzione di callback. Le funzioni di callback che rientrano in questa categoria si aspettano anche che tutto ciò di cui hanno bisogno per funzionare correttamente sia fornito attraverso argomenti alla funzione. Ciò potrebbe comportare anche la modifica del contenuto degli argomenti.

  3. Quelli che restituiscono dati più complessi o diversi rispetto ai primi due sono inusuali. Non ricordo di averne visto nel mio lavoro o in altri posti. Se stai pensando di utilizzare i callback di questa categoria, probabilmente hai pensato a questo bene e il tuo team, se sei in una squadra, è convinto che questo sia l'approccio corretto.

    Se non hai pensato a questo, vorrei usare le funzioni di callback che appartengono alle prime due categorie.

risposta data 03.06.2014 - 18:27
fonte
1

Non mi piacciono le funzioni che modificano le mie variabili, quindi preferisco usare il valore restituito e quindi posso decidere cosa fare con quel valore. Occasionalmente è utile dire restituire un valore booleano che indica se un valore è stato modificato e la funzione modificare il valore. Ciò può far risparmiare tempo e codice, ma in generale preferirei rilasciare queste due informazioni in un contenitore e restituirle.

    
risposta data 03.06.2014 - 18:38
fonte
0

Risposta breve:

Quando devi chiamare molte funzioni lungo la linea, è meglio che i callback modifichino lo stato di un oggetto piuttosto che restituire qualcosa.

Quando non hai davvero bisogno di chiamare molte funzioni, va bene se la richiamata restituisce qualcosa.

Risposta lunga:

Quando il framework in questione è coinvolto nell'invio di una catena di messaggi (o in altre parole, chiama un sacco di routine / funzioni) che controllano il comportamento dell'applicazione, allora andremmo a modificare il valore di una variabile o di un stato dell'oggetto anziché restituire qualcosa indietro.

Un buon esempio di questo è Windows Form.

Un articolo dettagliato su di esso sarà collegato a più tardi.

In breve comunque

  • windows forms è un framework che astrae tutta la gestione dei messaggi di basso livello, caratteristica di un'app basata su gui.
  • Durante tutta la durata dell'applicazione, l'app riceve messaggi dal sistema operativo (lo legge da una coda) e invia messaggi (al sistema operativo).
  • Di solito quando un messaggio viene consumato, si traduce in un "evento" nella nostra applicazione.

    • Nell'applicazione classica di Windows (utilizzando API pura o winapi) ci occupiamo solo di alcuni messaggi (come chiusura, clic, ecc.).
    • Il framework dei moduli di Windows gestisce comunque "tutti" i messaggi.
    • Un'app di Windows Form in genere si iscrive a un sottoinsieme degli eventi; quindi essenzialmente le app rispondono a un sottoinsieme dei messaggi

La maggior parte di questi eventi modifica lo stato di un oggetto passato ad esso come argomento in base al quale il framework decide come rispondere. Il framework deve inviare messaggi al sistema operativo e ricevere messaggi dalla coda. Ci sono funzioni standard per questo (definito dall'API, ovviamente).

In questo caso, leggere lo stato di un oggetto mutato (e quindi decidere quale messaggio inviare al sistema operativo) serve per essere "più veloce". (Immagina questo in termini di come si eseguiranno le istruzioni di assemblaggio).

Ora quando vorresti utilizzare un ritorno?

In poche parole, direi, quando non devi chiamare così tante funzioni diverse su tutta la linea. Un buon esempio è ogni iteratore di jQuery.

$.each([1, 2, 3, 4], function foo(_, v) {
   if(v === 2) return false;
   console.log(v);
});

In questo caso jQuery chiama semplicemente la funzione foo (nome dato per l'amor di riferimento), e non qualsiasi altra cosa, quindi una richiamata che restituisce qualcosa è "conveniente" qui. Rende anche una migliore comprensione del codice.

    
risposta data 03.06.2014 - 19:36
fonte

Leggi altre domande sui tag