2016-11-24 29 views
0

node.jsのES6ネイティブ約束を使用してクエリを呼び出す方法以下はコードです。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)を実行すると空の応答が表示されます。私は正しい方法で約束を使用したかどうかは分かりませんが、私は約束でも実行しなければならない最初の照会について考えます。どんな助けも大変ありがとうございます

+0

ce.length == 0とした場合、エラーはありませんか? –

+0

@GrantParkはい私はエラーがないことを確認しましたが、実際には2番目のクエリの前にconsole.logを配置していますが、その後はクエリデータを見ることはできませんが、長さ== 0 –

+0

その場合は、2番目のクエリに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

私は1つの質問も約束する必要がありますか? –

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

この1時間を行うことで、あなたが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

ああ、良いキャッチ! :D – drinchev

関連する問題