MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Como faço para aninhar uma promessa dentro de outra função de promessa no node.js?


Cercando tudo por uma new Promise ligar não ajuda em nada. Dentro dele, você ainda teria callback hell. E não, jogando Promise.resolve() em uma função que não retorna nada também não ajuda.

Você precisará promessa as primitivas assíncronas, ou seja, as menores partes que são assíncronas. No seu caso, é distance.matrix e o connect do mongo +insert :
function getMatrix(m, o, d) {
    return new Promise(function(resolve, reject) {
        m.matrix(o, d, function(err, distances) {
            if (err) reject(err);
            else     resolve(distances);
        });
    });
}

function save(url, store, k) {
// cramming connect+insert in here is not optimal but let's not get into unnecessary detail
    return new Promise(function(resolve, reject) {
        MongoClient.connect(url, function(err, db) {
            if (err)
                reject(err);
            else
                db.collection(k).insert(store, function(err, results) {
                    if (err) reject(err);
                    else     resolve(results);
                    db.close();
                });
        });
    });
}

Agora que temos isso, podemos realmente usá-los e combinar nossas promessas no que você realmente está procurando:
module.exports = Promise.all(dep.map(function(name) {
    distance.departure_time(name);
    return getMatrix(distance, origins, destinations).then(function(distances) {
        if (!distances) throw new Error('no distances');
        var promises = [];
        if (distances.status == 'OK') {
            for (var i=0; i < origins.length; i++) {
                for (var j = 0; j < destinations.length; j++) {
                    var origin = distances.origin_addresses[i];
                    var destination = distances.destination_addresses[j];
                    if (distances.rows[0].elements[j].status == 'OK') {
                        var duration = distances.rows[i].elements[j].duration_in_traffic.value;
                        var myobj = {
                            destination: destination,
                            departure_time: name,
                            duration: duration
                        };
                        var str = destination.replace(/[,\s]+/g, '');
                        promises.push(save(url, myobj, str));
//                                    ^^^^^^^^^^^^^^^^^^^^^
                    }
                }
            }
        }
        return Promise.all(promises); // now wait for all save results
    });
}));