ฉันเจอโค้ดพังพอนชิ้นหนึ่งที่มีเคียวรี findOne และฟังก์ชัน exec ()
ฉันไม่เคยเห็นวิธีการนั้นใน Javascript มาก่อน? มันทำอะไรกันแน่?
ฉันเจอโค้ดพังพอนชิ้นหนึ่งที่มีเคียวรี findOne และฟังก์ชัน exec ()
ฉันไม่เคยเห็นวิธีการนั้นใน Javascript มาก่อน? มันทำอะไรกันแน่?
คำตอบ:
โดยทั่วไปเมื่อใช้พังพอนสามารถดึงเอกสารได้โดยใช้ตัวช่วย ทุกเมธอดโมเดลที่ยอมรับเงื่อนไขเคียวรีสามารถดำเนินการได้โดยใช้ a callback
หรือexec
เมธอด
callback
:
User.findOne({ name: 'daniel' }, function (err, user) {
//
});
exec
:
User
.findOne({ name: 'daniel' })
.exec(function (err, user) {
//
});
ดังนั้นเมื่อคุณไม่ส่งการโทรกลับคุณสามารถสร้างแบบสอบถามและดำเนินการได้ในที่สุด
ท่านสามารถหาข้อมูลเพิ่มเติมในเอกสารพังพอน
อัปเดต
สิ่งที่ควรทราบเมื่อใช้Promisesร่วมกับการดำเนินการแบบ async ของ Mongoose คือการค้นหาพังพอนไม่ใช่คำสัญญา ข้อความค้นหาจะส่งคืนที่ตอบได้ แต่ถ้าคุณต้องการคำสัญญาจริงคุณควรใช้exec
วิธีนี้ ข้อมูลเพิ่มเติมสามารถพบได้ที่นี่
ในระหว่างการอัปเดตฉันสังเกตเห็นว่าฉันไม่ได้ตอบคำถามอย่างชัดเจน:
ฉันไม่เคยเห็นวิธีการนั้นใน Javascript มาก่อน? มันทำอะไรกันแน่?
มันไม่ใช่วิธีดั้งเดิมของ JavaScript แต่เป็นส่วนหนึ่งของ Mongoose API
exec
วิธีการนี้ นี่คือสิ่งที่พวกเขาทำในเอกสารอย่างน้อยที่สุด Model.find() instanceof require('bluebird')
เพื่อให้แน่ใจว่าคุณสามารถตรวจสอบตัวเองด้วย หวังว่านี่จะช่วยได้
Model.update().exec()
แน่ใจว่าจะดำเนินการได้ จากนั้นคุณสามารถตอบสนองต่อ API ได้โดยไม่ต้องรอการอัปเดต
แดเนียลตอบเรื่องนี้ได้อย่างสวยงามทีเดียว ในการอธิบายรายละเอียดเกี่ยวกับวิธีการสร้างและดำเนินการสืบค้นโดยละเอียดให้ดูที่กรณีการใช้งานต่อไปนี้
อาคารแบบสอบถาม
พังพอนจะไม่ดำเนินการค้นหาจนกว่าthen
หรือexec
ถูกเรียกใช้ สิ่งนี้มีประโยชน์มากเมื่อสร้างแบบสอบถามที่ซับซ้อน ตัวอย่างบางส่วนอาจรวมถึงการใช้ฟังก์ชันpopulate
และaggregate
User.find({name: 'John'}) // Will not execute
ดำเนินการผ่านการโทรกลับ
แม้ว่าหลาย ๆ คนจะไม่ชอบเนื่องจากลักษณะการซ้อนกัน แต่การสืบค้นสามารถดำเนินการได้โดยระบุการเรียกกลับที่เป็นทางเลือก
User.find({name: 'John'}, (err, res) => {}) // Will execute
จากนั้น API เป็นสัญญา / A +
คำค้นหาพังพอนมีthen
ฟังก์ชัน นี่ไม่ต้องสับสนกับคำสัญญาปกติ พูดง่ายๆก็คือข้อกำหนดของสัญญา / A + ต้องการthen
ฟังก์ชันที่จะทำงานเหมือนกับที่เราคุ้นเคยกับคำสัญญา
User.find({name: 'John'}).then(); // Will execute
Promise.all([User.find({name: 'John'}), User.find({name: 'Bob'})]) // Will execute all queries in parallel
ฟังก์ชัน exec
จาก Mongoose docs If you need a fully-fledged promise, use the .exec() function.
User.find({name: 'John'}).exec(); // Will execute returning a promise
then
ในแบบสอบถามเพื่อคืนสัญญาได้เช่นกัน สิ่งนี้ไม่แตกต่างจากexec
. Promise.all
กรณีการใช้งานที่ฉันพบนี้มีประโยชน์คือเมื่อใช้สิ่งที่ต้องการ ไม่แน่ใจว่าสัญญาที่ส่งคืนมาจากการexec
ทำงานในบริบทดังกล่าวหรือไม่
exec()
จะคืนคำสัญญาหากไม่มีการโทรกลับ ดังนั้นรูปแบบต่อไปนี้จึงสะดวกและทั่วไปมาก - สามารถจัดการกับการโทรกลับหรือสัญญาได้อย่างดี:
function findAll(query, populate, cb) {
let q = Response.find(query);
if (populate && populate.length > 0) {
q = q.populate(populate);
}
// cb is optional, will return promise if cb == null
return q.lean().exec(cb);
}
ฉันขอแนะนำให้ใช้ Bluebird สัญญากับพังพอนในการทำเช่นนั้นใช้การโทรนี้:
const mongoose = require('mongoose');
mongoose.Promise = require('bluebird');