2016-10-08 107 views
3

我正在使用Node.js和Sequelize(使用Postgres後端)構建網站。我有一個查詢使用外鍵返回多個對象,並且我想傳遞給外鍵列表引用的對象列表。同步執行Sequelize查詢

在這個例子中,Attendances包含Hackathon鍵,我想返回一個黑客馬拉松列表。由於代碼是異步的,當然以後的事不會在節點工作:

models.Attendance.findAll({ 
    where: { 
     UserId: req.user.id 
    } 
}).then(function (data) { 
    var hacks = []; 
    for (var d in data) { 
     models.Hackathon.findOne({ 
      where: { 
       id: data[d].id 
      } 
     }).then(function (data1) { 
      hacks.append(data1); 
     }); 
    } 
    res.render('dashboard/index.ejs', {title: 'My Hackathons', user: req.user, hacks: hacks}); 
}); 

有沒有辦法做到在同步方式查詢,這意味着我不回的觀點,直到我有「黑客」名單充滿了所有的對象?

謝謝!

+0

你嘗試異步模塊瀑布?那可以幫助你 – abdulbarik

+0

找到循環中的一條記錄是一種可怕的設計方式。它應該只是一個查詢。 –

回答

3

使用Promise.all執行所有查詢,然後調用下一個函數。

models.Attendance.findAll({ 
 
    where: { 
 
     UserId: req.user.id 
 
    } 
 
}).then(function (data) { 
 
    // get an array of the data keys, (not sure if you need to do this) 
 
    // it is unclear whether data is an object of users or an array. I assume 
 
    // it's an object as you used a `for in` loop 
 
    const keys = Object.keys(data) 
 
    // map the data keys to [Promise(query), Promise(query), {...}] 
 
    const hacks = keys.map((d) => { 
 
     return models.Hackathon.findOne({ 
 
     where: { 
 
      id: data[d].id 
 
     } 
 
     }) 
 
    }) 
 
    // user Promise.all to resolve all of the promises asynchronously 
 
    Promise.all(hacks) 
 
     // this will be called once all promises have resolved so 
 
     // you can modify your data. it will be an array of the returned values 
 
     .then((users) => { 
 
     const [user1, user2, {...}] = users 
 
     res.render('dashboard/index.ejs', { 
 
      title: 'My Hackathons', 
 
      user: req.user, 
 
      hacks: users 
 
     }); 
 
     }) 
 
});

1

你重新發明輪子,該Sequelize庫已經擁有這一切想出來的。你提到你已經建立了外鍵,超過一半的戰鬥完成。

使用包括在您的where語句引入Hackathons模型,在一個呼叫。如果您的環境設置正確,這將工作。花時間在圖書館下正確地設置,您可以通過減少錯誤來節省大量時間,並在需要時允許其他人從您離開的地方取回。

看,這多少吸塵器......

models.Attendance.findAll({ 
    include: [{ 
     model: Hackathon, 
     as: 'hackathon' 
    }, 
    where: { 
     UserId: parseInt(req.user.id) // <---- like to parseInt to prevent SQL injection, but I believe Sequelize already covers this, can never be too safe ;-) 
    } 
}).then(function (data) { 
    // hackathon id 
    console.log(data.hackathon.id) 

    // attendance id 
    console.log(data.id) 
}) 

瞭解更多關於Sequelize包括在這裏: http://docs.sequelizejs.com/en/latest/docs/models-usage/

+0

你幾乎可以太安全。如果您只是將所有內容都包裝在parseInt()調用中,因爲「可能」,那麼您就是貨運代理。 – theraccoonbear