所有问题都不能按正确的顺序解决
Q.all doesnt resolve in correct order
我对Node.js中Q的承诺的执行顺序有问题。
代码应该做以下事情:
a)执行查询并使用得到的纬度/长度对
b)计算最短路径(使用异步函数)和
c)返回 query() // Runs the query
.then(function() {
return computeRoutes(); // Calculates the routes
})
.then(function() {
return returnRoutes(); // Returns the routes as JSON
});
问题是,虽然坐标[]数组在query()中填充,并在computeRoutes()中填充/可用,但routes[]数组在returnRoutes()中仍然为空。
奇怪的是,当我在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();
});
});
试错后找到了答案。
问题是我使用for..in循环在computeRoutes()函数中生成承诺。
切换到带函数的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();
});
相关文章:
- ajax请求的顺序总是不同的
- 按照选项卡索引的顺序循环一个jQuery选择
- 匹配一个单词,其中候选人可以跨越顺序组(跨度)
- 如何解决Yii中的页面刷新问题
- 按顺序添加和删除类
- 测试Angular Service解决错误回调中的promise
- 按我自己的类克隆另一个元素的内容和顺序
- Javascript-根据赋值顺序,按键合并对象数组
- 2个backbone.js集合,具有相同的模型,但排序顺序不同
- querySelector/getElementByClassName嵌套项的顺序
- 如何解决Access Control Allow Origin错误
- 如何解决这种情况下的非法调用类型错误
- Javascript文件依赖项未通过清单顺序解决
- JavaScript 循环输出顺序不正确 - 如何解决这个问题
- 需要一个优化的解决方案来获取按字母顺序排列的记录集 javascript
- JS加载顺序 - 滚动JS禁用,回调解决方案,或者更简单
- 承诺的解决顺序是否与Promise.sexel中提到的顺序相同
- 如何保证多个承诺的解决顺序
- 所有问题都不能按正确的顺序解决
- 是否有已知的解决方案IE9'注入脚本标签的执行顺序