Q.all没有按照正确的顺序解决

我在Node.js中Q的承诺的执行顺序遇到问题。

该代码应该执行以下操作:

a)执行一个查询并使用得到的纬度/经度对

b)计算最短path(使用asynchronous函数)和

c)返回他们

query() // Runs the query .then(function() { return computeRoutes(); // Calculates the routes }) .then(function() { return returnRoutes(); // Returns the routes as JSON }); 

问题是,虽然coordinates []数组在query()中填充,并且在computeRoutes()中填充/可用,但在returnRoutes()中,routes []数组仍为空。

奇怪的是,当我不在computeRoutes()中的坐标[]上循环,而只是计算一个坐标[0]的路线,承诺链成功(但我知道只有一条路线返回为JSON)

任何想法在这里可能是错的?

谢谢!!

完整代码:

 app.get('/', function(req, res) { var id = parseInt(req.query.id); var radius = parseInt(req.query.radius) || 5000; var routes = []; var coordinates = []; function query() { var deferred = Q.defer(); console.log('Starting query function...'); var query = client.query('SELECT ST_X(ST_Transform(ST_SetSRID(a.geom, 3857),4326)) AS fromlat, ST_Y(ST_Transform(ST_SetSRID(a.geom, 3857),4326)) AS fromlon, ST_X(ST_Transform(ST_SetSRID(b.geom, 3857),4326)) AS tolat, ST_Y(ST_Transform(ST_SetSRID(b.geom, 3857),4326)) AS tolon FROM emme_veh AS c, emme_nodes3857 AS b, emme_nodes3857 AS a WHERE c.fid = a.id AND c.tid = b.id AND c.fid = $1 AND ST_Distance(a.geom, b.geom) < $2', [id, radius], function(err, result) { console.log('Inside query. result.rows.length:',result.rows.length); for(var i in result.rows) { coordinates.push({'from':[result.rows[i].fromlon,result.rows[i].fromlat], 'to':[result.rows[i].tolon,result.rows[i].tolat]}); } deferred.resolve(); }); return deferred.promise; } function computeRoutes() { var the_promises = []; for(var i in coordinates) { var deferred = Q.defer(); var query = {coordinates: [coordinates[i].from, coordinates[i].to], alternateRoute: false} osrm.route(query, function(err, result) { if(err) return res.json({"error": err.message}); // console.log(result.route_geometry); routes.push(result.route_geometry); deferred.resolve(); }); the_promises.push(deferred.promise); } return Q.all(the_promises); } function returnRoutes() { return res.json(routes); } query() .then(function() { return computeRoutes(); }) .then(function() { return returnRoutes(); }); }); 

经过一些试用n错误后find了答案。

问题是我正在使用for..in循环在computeRoutes()函数中生成promise。

切换到function的forEach循环做了诀窍。

工作代码片段(查看computeRoutes()部分):

 app.get('/', function(req, res) { var id = parseInt(req.query.id); var radius = parseInt(req.query.radius) || 5000; var routes = []; var coordinates = []; function query() { var deferred = Q.defer(); console.log('Starting query function...'); var query = client.query('SELECT ST_X(ST_Transform(ST_SetSRID(a.geom, 3857),4326)) AS fromlat, ST_Y(ST_Transform(ST_SetSRID(a.geom, 3857),4326)) AS fromlon, ST_X(ST_Transform(ST_SetSRID(b.geom, 3857),4326)) AS tolat, ST_Y(ST_Transform(ST_SetSRID(b.geom, 3857),4326)) AS tolon FROM emme_veh AS c, emme_nodes3857 AS b, emme_nodes3857 AS a WHERE c.fid = a.id AND c.tid = b.id AND c.fid = $1 AND ST_Distance(a.geom, b.geom) < $2', [id, radius], function(err, result) { console.log('Inside query. result.rows.length:',result.rows.length); for(var i in result.rows) { coordinates.push({'from':[result.rows[i].fromlon,result.rows[i].fromlat], 'to':[result.rows[i].tolon,result.rows[i].tolat]}); } deferred.resolve(); }); return deferred.promise; } function computeRoutes() { var the_promises = []; console.log('Inside computeRoutes()'); coordinates.forEach(function(coordinate) { var deferred = Q.defer(); osrm.route({coordinates: [coordinate.from, coordinate.to], alternateRoute: false}, function(err, result) { deferred.resolve(result); routes.push(result.route_geometry); }); the_promises.push(deferred.promise); }); return Q.all(the_promises); } function returnRoutes() { console.log('Inside returnRoutes()'); return res.json(routes); } query() .then(function() { console.log('then() 1'); return computeRoutes(); }) .then(function() { console.log('then() 2'); return returnRoutes(); });