2016-11-24 3 views
0

как я могу вызвать запрос, используя собственные обещания ES6 в node.js. Ниже приведен код.Возвращение пустого ответа с использованием обещания ES6 в node.js

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 yes Я проверил, что нет ошибки, на самом деле я поместил console.log перед вторым запросом, и после этого я могу увидеть журнал, но не данные запроса, но все же я повторю это снова с case ce. 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); 
    }); 
}) 

Edit: Ref: 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); 
     } 
    }) 
}); 

Делая это один раз, вы будете держать свой код 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) 
+0

, вы забыли обработать параметры, передающие запрос в примере :) – iKoala

+0

Ahh, Good catch! : D – drinchev

Смежные вопросы