How do i nest a promise inside another promise fun

2019-07-25 04:42发布

问题:

I have a file file which is surrounded by Promise function . I have a database operation inside this function which requires another promise too . Please check the code below

var p ;
var ted = dep.map(function(name){

return new Promise(function(resolve,reject){ 
    /*..list of other tasks*/
    for(int i = 0 ;i<3<;i++){        
      p = Promise.resolve(savemongo(myobj,str));  // this is async function. How do I wait till this operation is complete and then move to next
    } 
  resolve();

)};

Now i have to export this module to a different file

Im using the below code

module.exports = Promise.all([ted,p]);

How do I wait till my savetomongodb function is complete .

回答1:

Surrounding the whole thing by one new Promise call doesn't help anything. Inside it, you'd still have callback hell. And no, throwing Promise.resolve() at a function that doesn't return anything doesn't help either.

You will need to promisify the asynchronous primitives, i.e. the smallest parts that are asynchronous. In your case, that's distance.matrix and mongo's connect+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();
                });
        });
    });
}

Now that we have those, we can actually use them and combine our promises into what you actually are looking for:

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
    });
}));