2016-11-24 56 views
0

如何使用node.js中的ES6原生承诺调用查询?以下是代码。在node.js中使用ES6承诺返回空响应

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)。我不知道我是否以正确的方式使用了承诺,我认为对于第一次查询,我也应该在承诺中执行。任何帮助都非常感谢

+0

您是否考虑过ce.length == 0并且没有错误的情况? –

+0

@GrantPark是的,我已经检查没有错误,实际上我已经在第二个查询之前放置了console.log,之后我可以看到一个日志但没有查询数据,但是我仍然会再次检查该情况。 length == 0 –

+0

在这种情况下,还要在第二个查询中放置一个console.log,看看是否运行。 –

回答

0

您从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

+0

感谢它的工作:) –

+0

我有一个问题应该第一个查询也承诺吗? –

+0

是的,你应该。对整个应用程序使用承诺或回调是一个很好的做法,但不能同时支持更好的代码管理和可读性。其实来自@drinchev的示例代码非常干净且有帮助。检查一下,如果你能理解它。 – iKoala

2

结束语一个基于异步回调函数为一个承诺被称为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); 
     } 
    }) 
}); 

通过这样做一次,你会保持你的代码干,你可以随时使用这个承诺现在进行查询:

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) 
+0

你忘了处理传递给查询中的参数例:) – iKoala

+0

啊,好抓! :d – drinchev