【问题标题】:Returning empty response using ES6 promise in node.js在 node.js 中使用 ES6 Promise 返回空响应
【发布时间】:2016-11-25 03:59:03
【问题描述】:

如何在 node.js 中使用 ES6 原生 Promise 调用查询。下面是代码。

let arr= [];
    conn.query('select * from table1', (err, b) => {
    for (let i = 0; i < b.length; i++) {
        console.log(b[i]["id"])
        let promiseGetData = new Promise((resolve, reject) => {
            conn.query('select * from table2 where id = ?', [b[i]["id"]], (err, ce) => {
                if (err) {
                    const response = {
                        statusCode: 500,
                        body: JSON.stringify({
                            message: err
                        }),
                    }
                    reject(response);
                } else {
                    if (ce.length != 0) {
                        resolve(ce);
                    }
                }
            });
        });

        promiseGetData .then((data) => {
            b[i]['data'] = data;
            arr.push(b[i])
        }).catch((err) => {
            console.log(err);
        });
    }
console.log(b)
    })

我在执行 console.log(b) 时看到一个空响应。我不知道我是否以正确的方式使用了诺言,我认为对于第一个查询,我也应该在诺言中执行。非常感谢任何帮助

【问题讨论】:

  • 你考虑过ce.length == 0且没有错误的情况吗?
  • @GrantPark 是的,我已经检查过没有错误,实际上我已经在第二次查询之前放置了 console.log,我可以看到日志但之后看不到查询数据,但我仍然会加倍用 case ce.length == 0 再次检查
  • 在这种情况下,还要在第二个查询中放置一个 console.log 并查看它是否运行。

标签: javascript node.js promise es6-promise


【解决方案1】:

将基于异步回调的函数包装到 Promise 中称为 Promisifying

您当然可以为此使用库,但基本上它的作用是:

const queryAsPromise = function( ...args ) {
    return new Promise( function( resolve, reject ) {
       try { 
           conn.query(...args, function( error, result ) {
               if ( error ) { 
                   reject( error );
               } else {
                   resolve( result );
               }
           } ); 
       } catch( error ) {
           reject( error );
       }
    } )
} );

通过这样做一次,您将保持代码 DRY,并且您现在可以随时使用该承诺进行查询:

queryAsPromise('select * from table1')
     .then( result => {
          return Promise.all(
              result.map( b => {
                 return queryAsPromise('select * from table2 where id = ?', b["id"])
                             .then( data => b["data"] = data )
              } )
          )
     )
     .catch( err => res.send(500) )
     .then( console.log )

【讨论】:

  • 您忘记处理示例中传递给查询的参数 :)
  • 啊,好球! :D
【解决方案2】:

您从 console.log(b) 得到空响应,因为查询数据库的承诺尚未完成。您必须等待所有这些都完成才能获得完整的结果。

示例:

let arr = [];
conn.query('select * from table1', (err, b) => {

  var promiseArr = [];

    for (let i = 0; i < b.length; i++) {
        let promiseGetData = new Promise((resolve, reject) => {
            conn.query('select * from table2 where id = ?', [b[i]["id"]], (err, ce) => {
                if (err) {
                    const response = {
                        statusCode: 500,
                        body: JSON.stringify({
                            message: err
                        }),
                    }
                    reject(response);
                } else {
                    if (ce.length != 0) {
                        resolve(ce);
                    }
                }
            });
        });

            promiseArr.push(promiseGetData);
    }

    Promise.all(promiseArr).then((resultArr) => {
        //resultArr is all the resolved value returned from the promise in promiseArr
        for (let i = 0; i < resultArr.length; i++) {
            b[i]['data'] = resultArr[i];
            arr.push(b[i]);
        }
    }).then(() => {
        console.log(arr);
    }).catch((err) => {
        //if any promise throw/reject with error, it will go here directly
            console.log(err);
    });
})

编辑: 参考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

【讨论】:

  • 我有一个问题,第一个查询是否也应该兑现?
  • 是的,你应该这样做。对整个应用程序使用 Promise 或回调是一个很好的做法,但不能同时支持更好的代码管理和可读性。实际上来自@drinchev 的示例代码非常干净和有用。如果你能理解,请检查它。
  • @iKoala 谢谢我会检查它
猜你喜欢
  • 2016-04-25
  • 1970-01-01
  • 2020-07-11
  • 2016-08-01
  • 1970-01-01
  • 2018-03-12
  • 2021-07-19
  • 2014-08-02
相关资源
最近更新 更多