Javascript 带循环的节点承诺

Javascript 带循环的节点承诺,javascript,node.js,promise,backend,Javascript,Node.js,Promise,Backend,这是我的问题: 我正在向数据库中的一个表发出请求,根据该请求的结果,我要向另一个表发出两个请求,这两个请求的结果要将它们添加到主请求中(首先)。问题是,这两个请求实际上是被提出的,但是当试图将这两个请求的结果都放在主结果中时,我不允许这样做。第二个循环在第一个循环未结束时也会运行(假设在第一个循环结束时结束) 也许这个错误很愚蠢,我是个有承诺的新手 谢谢 提取代码: var express = require("express"); var app = express(); var Promis

这是我的问题:

我正在向数据库中的一个表发出请求,根据该请求的结果,我要向另一个表发出两个请求,这两个请求的结果要将它们添加到主请求中(首先)。问题是,这两个请求实际上是被提出的,但是当试图将这两个请求的结果都放在主结果中时,我不允许这样做。第二个循环在第一个循环未结束时也会运行(假设在第一个循环结束时结束)

也许这个错误很愚蠢,我是个有承诺的新手

谢谢

提取代码:

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

对承诺有困难是可以的。这是一件棘手的事情

首先,不要谈论承诺和问题

关于你的问题。问题是承诺是异步的,而for循环不是。您需要使用map循环并返回它。它将保证所有行动都将完成,并且只有在第二次承诺开始之后。有两种方法:

  • 使用承诺(ES6):
    return Promise.all(你的元素的数组)。map(elem=>{
    //一些行动
    // ...
    返回;
    }))

  • 使用异步等待(ES7):
    async function\u name(){
    等待*数组中的元素。映射(元素=>{
    //一些行动
    // ...
    返回;
    })
    }

我更喜欢第二条路

重要信息:您应该始终在地图中使用回车键。它可以是空返回(如示例中所示)或其他内容。例如,如果您在每次迭代时返回字符串,它将给您一个包含字符串的承诺数组


享受承诺

假设您的
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()
    ,以便每次迭代都返回一个表示两个子查询的承诺
  • 返回单个项作为每次迭代的结果
  • 当所有迭代和子查询完成后,您应该得到一个结果数组

  • for循环的返回将在一次迭代后终止循环第二次,然后不要等待第一次承诺已解决好答案,现在我得到了以下结果: