nidificazione di JavaScript e di callback

4

Molte librerie JavaScript (in particolare jQuery) usano il concatenamento, che consente la riduzione di questo:

var foo = $(".foo");
foo.stop();
foo.show();
foo.animate({ top: 0 });

a questo:

$(".foo").stop().show().animate({ top: 0 });

Con una formattazione corretta, penso che questa sia una buona capacità sintattica. Tuttavia, vedo spesso uno schema che non mi piace particolarmente, ma che sembra essere un male necessario nei modelli non bloccanti. Questo è l'annidamento sempre presente delle funzioni di callback:

$(".foo").animate({
    top: 0,
}, {
    callback: function () {
        $.ajax({
            url: 'ajax.php',
        }, {
            callback: function () { ... }
        });
    }
});

E non finisce mai. Anche se mi piace la semplicità dei modelli non bloccanti, odio lo strano nidificazione dei letterali delle funzioni che impone al programmatore.

Sono interessante nello scrivere una piccola libreria JS come esercizio, e mi piacerebbe trovare un modo migliore per farlo, ma non so come si possa fare senza sentirsi hacky. Ci sono progetti là fuori che hanno risolto questo problema prima? E se no, quali sono le alternative a questa brutta e insignificante struttura del codice?

    
posta Alexis King 12.12.2012 - 20:36
fonte

2 risposte

9

Solo perché puoi usare le funzioni anonime (lambda) per questo tipo di costrutto non significa che hai . Proprio come è buona norma estrarre la sintassi della costruzione di un valore complesso da una chiamata di funzione e nella sua variabile, puoi fare lo stesso con i tuoi valori letterali di funzione. Osservare:

// Your example:
$(".foo").animate({
    top: 0,
}, {
    callback: function () {
        $.ajax({
            url: 'ajax.php',
        }, {
            callback: function () { ... }
        });
    }
});

// Can be rewritten as:
var animateProps = { top: 0 };
var animateCallback = function() {
    var ajaxProps = { url: 'ajax.php'; }
    var ajaxCallback = function () { ... }
    $.ajax(ajaxProps, {callback: ajaxCallback});
};
$(".foo").animate(animateProps, {callback: animateCallback});

// Or even, depending on what you do inside the ajax callback:
var animateProps = { top: 0 };
var ajaxProps = { url: 'ajax.php'; }
var ajaxCallback = function () { ... }
var animateCallback = function() {
    $.ajax(ajaxProps, {callback: ajaxCallback});
};
$(".foo").animate(animateProps, {callback: animateCallback});

E tutta la brutta sintassi annidata è sparita!

Si noti, tuttavia, che lo stile nested-anonimo non è poi così male; dopotutto, se le chiamate di funzione seguono una struttura logica, anche la funzione chiama i raggruppamenti. Esempio:

doAsyncSomething(
    function(successData){
        alert("All is well!");
    },
    function(errorMessage){
        alert("Oh no! Something went wrong! Namely: " + errorMessage);
    });

In questo esempio, il nesting del codice segue la struttura logica abbastanza bene.

    
risposta data 12.12.2012 - 20:57
fonte
3

Personalmente mi piace questo stile, come bonus aggiuntivo ottieni funzioni con nome, il che è molto utile per il debug:

$(".foo").animate({
    top: 0,
}, {
    callback: animateCallback 
});

function animateCallback() {
    $.ajax('ajax.php', ajaxCompleted);
}

function ajaxCompleted() {
    // ...
}

Nella mia esperienza, il più delle volte non si desidera realmente avere funzioni anonime. Per esempio, mi sono ritrovato a generare eventi su pulsanti, perché ho associato una funzione particolare a un listener di eventi, anziché a una funzione indipendente.

    
risposta data 13.12.2012 - 07:51
fonte

Leggi altre domande sui tag