Un modo giusto per progettare il flusso javascript?

0

La mia domanda è perché credo che forse c'è un modo migliore per progettare il mio codice quando devo eseguire attività di sincronizzazione in JS e attendere la risposta.

Sto lavorando su Node e ho bisogno di salvare alcuni dati (ho una funzione che lo fa), ma ho bisogno di eseguire alcuni controlli prima (vs il database) che sono anche chiamate asincrone.

Semplificheremo codice ed esempi:

function save(req, res) {
    var id = req.param('id');
    var name = req.param('name');

    if (id) {
        // Here come the checks, e.g., there is no limit in number of items on DB
        mymodule.getConfig("maxItems", function(data) {
            if (data.success) {
                // max = 0 means unlimited items
                if (data.maxItems == 0) {
                    // Just continue, all fine

                } else {
                    mymodule.countItems(function(data) {
                        if (data.success) {
                            if (data.count >= maxItems) {
                                res.render('myPage', {error: 'You have reached the maximun items'});
                            }
                        } else {
                            res.render('myPage', {error: 'Error in DB'});
                        }
                    });
                }

            } else {
                res.render('myPage', {error: 'Error in DB'});
            }
        });

        // Save part (common code)
        mymodule.save({
            'id': id,
            'name': name
        }, function(data) {
            if (data.success) {
                res.render('myPage');
            } else {
                res.render('myPage', {error: 'Error while saving in DB'});
            }
        });

    } else {
        res.render('myPage', {error: 'Id is null'});
    }
}

Ovviamente questo non funzionerà perché i controlli verranno chiamati asincroni e il salvataggio verrà chiamato sempre, invece del reindirizzamento quando i controlli falliscono.

Il modo giusto è "duplicare" la parte di salvataggio nel posto giusto, in questo modo:

function save(req, res) {
    var id = req.param('id');
    var name = req.param('name');

    if (id) {
        // Here come the checks, e.g., there is no limit in number of items on DB
        mymodule.getConfig("maxItems", function(data) {
            if (data.success) {
                // max = 0 means unlimited items
                if (data.maxItems == 0) {
                    // Save part---------------------------
                    mymodule.save({
                        'id': id,
                        'name': name
                    }, function(data) {
                        if (data.success) {
                            res.render('myPage');
                        } else {
                            res.render('myPage', {error: 'Error while saving in DB'});
                        }
                    });

                } else {
                    mymodule.countItems(function(data) {
                        if (data.success) {
                            if (data.count >= maxItems) {
                                res.render('myPage', {error: 'You have reached the maximun items'});
                            } else {
                                // Save part-------------------------
                                mymodule.save({
                                    'id': id
                                    'name': name
                                }, function(data) {
                                    if (data.success) {
                                        res.render('myPage');
                                    } else {
                                        res.render('myPage', {error: 'Error while saving in DB'});
                                    }
                                });
                            }
                        } else {
                            res.render('myPage', {error: 'Error in DB'});
                        }
                    });
                }

            } else {
                res.render('myPage', {error: 'Error in DB'});
            }
        });

    } else {
        res.render('myPage', {error: 'Id is null'});
    }
}

Funziona ma è un modo sbagliato di codificare, duplicando lo stesso codice. Per rispettare il principio DRY, attualmente sto facendo una funzione con un callback con la parte di salvataggio, e chiamando quella funzione in ogni posto, come questa:

function saveData(id, name, function(onComplete) {
    mymodule.save({
        'id': id,
        'name': name
    }, function(data) {
        if (data.success) {
            onComplete('');
        } else {
            onComplete('Error while saving in DB');
        }
    });
});

function save(req, res) {
    var id = req.param('id');
    var name = req.param('name');

    if (id) {
        // Here come the checks, e.g., there is no limit in number of items on DB
        mymodule.getConfig("maxItems", function(data) {
            if (data.success) {
                // max = 0 means unlimited items
                if (data.maxItems == 0) {
                    // Save part---------------------
                    saveData(id, name, function(cb) {
                        res.render('myPage', {error: cb});
                    });
                } else {
                    mymodule.countItems(function(data) {
                        if (data.success) {
                            if (data.count >= maxItems) {
                                res.render('myPage', {error: 'You have reached the maximun items'});
                            } else {
                                // Save part---------------------
                                saveData(id, name, function(cb) {
                                    res.render('myPage', {error: cb});
                                });
                            }
                        } else {
                            res.render('myPage', {error: 'Error in DB'});
                        }
                    });
                }

            } else {
                res.render('myPage', {error: 'Error in DB'});
            }
        });

    } else {
        res.render('myPage', {error: 'Id is null'});
    }
}

Sto cercando un modo migliore per farlo perché sto ancora chiamando due (o più volte se necessario) la funzione saveData . Il flusso ideale era il primo, ma a causa della natura asincrona dei javascript, non posso creare un flusso "sequenziale" con "restituisce" con% chiamate dires per i controlli e una chiamata save unica alla fine se tutto funziona bene .

C'è un altro modo più semplice per realizzare questo?

    
posta Eagle 06.05.2015 - 13:54
fonte

0 risposte

Leggi altre domande sui tag