带循环的节点承诺
Node Promise with loop
这是我的问题:
我正在向我的数据库中的一个 table 发出请求,该请求的结果是我想向另一个 table 发出两个请求,这两个请求的结果想要添加他们的主要要求(第一)。问题是这两个请求实际上已经发出,但是当我试图将两者的结果都放在主要结果中时,我不会这样做。 The 2nd Then 也在第一个没有结束时运行(假设在第一个循环结束时结束)
可能错误很蠢,我是promises新手
谢谢
提取码:
var express = require("express");
var app = express();
var Promise = require('bluebird');
var bodyParser = require('body-parser')
var mysql = require('promise-mysql');
app.get('/misPartidos', function (req, res) {
var query = conexion.query('SELECT partidos.id_partido, partidos.id_torneo, partidos.nlocal, partidos.nvisitante, partidos.idlocal,partidos.idvisitante, partidos.jornada, partidos.glocal, partidos.gvisitante, partidos.fecha, torneos.nombre_torneo, partidos.estado, torneos.version, torneos.modo, torneos.tipo FROM partidos INNER JOIN equipos ON(equipos.id_equipo = partidos.idlocal OR equipos.id_equipo = partidos.idvisitante) INNER JOIN participantes ON(equipos.id_equipo = participantes.id_equipo AND equipos.id_torneo = participantes.idtorneo_part) INNER JOIN torneos ON(participantes.idtorneo_part = torneos.id_torneo) WHERE participantes.username = "'+ req.query.usuario + '" ORDER BY jornada ASC')
.then(function(success){
for(var x in success){
conexion.query('SELECT username,nombre_eq FROM equipos WHERE id_equipo = '+success[x].idlocal)
.then(function(local){
success[x].local = local[0].username;
});
conexion.query('SELECT username, nombre_eq FROM equipos WHERE id_equipo = '+success[x].idvisitante)
.then(function(visitante){
success[x].visitante = visitante[0].username;
});
return success;
}
}).then(function(resultado){
console.log(results);
}).catch(function(error){
console.log(error);
});
});
在承诺方面遇到麻烦是可以的。这是一件棘手的事情。
首先,保存这个great article关于承诺和问题。
关于你的问题。问题是 promise 是异步的,而 for-loop 不是。您需要使用 map-loop 和 return 它。它将保证所有动作都将完成,并且只有在第二个承诺之后才会开始。有两种方式:
使用 Promise (ES6):
return Promise.all( array_of_your_elements.map( elem => {
// some actions
// ...
return;
}))
使用异步等待(ES7):async function_name() {
await* array_of_your_elements.map( elem => {
// some actions
// ...
return;
})
}
我更喜欢第二种方式。
重要提示:您应该始终在地图中使用 return。它可以是空的 return(如示例中所示)或其他内容。如果你将 return,例如,在每次迭代中使用字符串,它会给你一个带有字符串的承诺数组。
享受承诺!
假设您的 success
参数是一个查询结果数组,您可以这样做:
var express = require("express");
var app = express();
var Promise = require('bluebird');
var bodyParser = require('body-parser')
var mysql = require('promise-mysql');
app.get('/misPartidos', function (req, res) {
var queryString = 'SELECT partidos.id_partido, partidos.id_torneo, partidos.nlocal, partidos.nvisitante, partidos.idlocal,partidos.idvisitante, partidos.jornada, partidos.glocal, partidos.gvisitante, partidos.fecha, torneos.nombre_torneo, partidos.estado, torneos.version, torneos.modo, torneos.tipo FROM partidos INNER JOIN equipos ON(equipos.id_equipo = partidos.idlocal OR equipos.id_equipo = partidos.idvisitante) INNER JOIN participantes ON(equipos.id_equipo = participantes.id_equipo AND equipos.id_torneo = participantes.idtorneo_part) INNER JOIN torneos ON(participantes.idtorneo_part = torneos.id_torneo) WHERE participantes.username = "'+ req.query.usuario + '" ORDER BY jornada ASC';
Promise.map(conexion.query(queryString), function(item) {
return Promise.all([
conexion.query('SELECT username,nombre_eq FROM equipos WHERE id_equipo = '+item.idlocal).then(function(local) {
item.local = local[0].username;
}),
conexion.query('SELECT username, nombre_eq FROM equipos WHERE id_equipo = '+item.idvisitante).then(function(visitante){
item.visitante = visitante[0].username;
})
]).then(function() {
// make the return value from `Promise.all()` be the item
// we were iterating
return item;
});
}).then(function(results) {
// array of results here
console.log(results);
}).catch(function(err) {
// error here
console.log(err);
});
});
这会执行以下操作:
- 使用 Bluebird 的
Promise.map()
遍历第一个查询的所有结果
- 在每次迭代中使用
Promise.all()
,以便每次迭代 returns 代表您执行的两个子查询的单个承诺。
- Return 作为每次迭代结果的单个项目
- 完成所有迭代和子查询后,您应该会得到一个结果数组。
这是我的问题:
我正在向我的数据库中的一个 table 发出请求,该请求的结果是我想向另一个 table 发出两个请求,这两个请求的结果想要添加他们的主要要求(第一)。问题是这两个请求实际上已经发出,但是当我试图将两者的结果都放在主要结果中时,我不会这样做。 The 2nd Then 也在第一个没有结束时运行(假设在第一个循环结束时结束)
可能错误很蠢,我是promises新手
谢谢
提取码:
var express = require("express");
var app = express();
var Promise = require('bluebird');
var bodyParser = require('body-parser')
var mysql = require('promise-mysql');
app.get('/misPartidos', function (req, res) {
var query = conexion.query('SELECT partidos.id_partido, partidos.id_torneo, partidos.nlocal, partidos.nvisitante, partidos.idlocal,partidos.idvisitante, partidos.jornada, partidos.glocal, partidos.gvisitante, partidos.fecha, torneos.nombre_torneo, partidos.estado, torneos.version, torneos.modo, torneos.tipo FROM partidos INNER JOIN equipos ON(equipos.id_equipo = partidos.idlocal OR equipos.id_equipo = partidos.idvisitante) INNER JOIN participantes ON(equipos.id_equipo = participantes.id_equipo AND equipos.id_torneo = participantes.idtorneo_part) INNER JOIN torneos ON(participantes.idtorneo_part = torneos.id_torneo) WHERE participantes.username = "'+ req.query.usuario + '" ORDER BY jornada ASC')
.then(function(success){
for(var x in success){
conexion.query('SELECT username,nombre_eq FROM equipos WHERE id_equipo = '+success[x].idlocal)
.then(function(local){
success[x].local = local[0].username;
});
conexion.query('SELECT username, nombre_eq FROM equipos WHERE id_equipo = '+success[x].idvisitante)
.then(function(visitante){
success[x].visitante = visitante[0].username;
});
return success;
}
}).then(function(resultado){
console.log(results);
}).catch(function(error){
console.log(error);
});
});
在承诺方面遇到麻烦是可以的。这是一件棘手的事情。
首先,保存这个great article关于承诺和问题。
关于你的问题。问题是 promise 是异步的,而 for-loop 不是。您需要使用 map-loop 和 return 它。它将保证所有动作都将完成,并且只有在第二个承诺之后才会开始。有两种方式:
使用 Promise (ES6):
return Promise.all( array_of_your_elements.map( elem => { // some actions // ... return; }))
使用异步等待(ES7):
async function_name() { await* array_of_your_elements.map( elem => { // some actions // ... return; }) }
我更喜欢第二种方式。
重要提示:您应该始终在地图中使用 return。它可以是空的 return(如示例中所示)或其他内容。如果你将 return,例如,在每次迭代中使用字符串,它会给你一个带有字符串的承诺数组。
享受承诺!
假设您的 success
参数是一个查询结果数组,您可以这样做:
var express = require("express");
var app = express();
var Promise = require('bluebird');
var bodyParser = require('body-parser')
var mysql = require('promise-mysql');
app.get('/misPartidos', function (req, res) {
var queryString = 'SELECT partidos.id_partido, partidos.id_torneo, partidos.nlocal, partidos.nvisitante, partidos.idlocal,partidos.idvisitante, partidos.jornada, partidos.glocal, partidos.gvisitante, partidos.fecha, torneos.nombre_torneo, partidos.estado, torneos.version, torneos.modo, torneos.tipo FROM partidos INNER JOIN equipos ON(equipos.id_equipo = partidos.idlocal OR equipos.id_equipo = partidos.idvisitante) INNER JOIN participantes ON(equipos.id_equipo = participantes.id_equipo AND equipos.id_torneo = participantes.idtorneo_part) INNER JOIN torneos ON(participantes.idtorneo_part = torneos.id_torneo) WHERE participantes.username = "'+ req.query.usuario + '" ORDER BY jornada ASC';
Promise.map(conexion.query(queryString), function(item) {
return Promise.all([
conexion.query('SELECT username,nombre_eq FROM equipos WHERE id_equipo = '+item.idlocal).then(function(local) {
item.local = local[0].username;
}),
conexion.query('SELECT username, nombre_eq FROM equipos WHERE id_equipo = '+item.idvisitante).then(function(visitante){
item.visitante = visitante[0].username;
})
]).then(function() {
// make the return value from `Promise.all()` be the item
// we were iterating
return item;
});
}).then(function(results) {
// array of results here
console.log(results);
}).catch(function(err) {
// error here
console.log(err);
});
});
这会执行以下操作:
- 使用 Bluebird 的
Promise.map()
遍历第一个查询的所有结果 - 在每次迭代中使用
Promise.all()
,以便每次迭代 returns 代表您执行的两个子查询的单个承诺。 - Return 作为每次迭代结果的单个项目
- 完成所有迭代和子查询后,您应该会得到一个结果数组。