Mongoose - Hàm thực thi làm gì?


100

Tôi đã xem qua một đoạn mã Mongoose bao gồm một truy vấn findOne và sau đó là một hàm executive ().

Tôi chưa bao giờ thấy phương pháp đó trong Javascript trước đây? Làm gì chính xác?

Câu trả lời:


144

Về cơ bản khi sử dụng mongoose, các tài liệu có thể được truy xuất bằng cách sử dụng trình trợ giúp. Mọi phương thức mô hình chấp nhận điều kiện truy vấn đều có thể được thực thi bằng phương thức a callbackhoặc execphương thức.

callback:

User.findOne({ name: 'daniel' }, function (err, user) {
  //
});

exec:

User
  .findOne({ name: 'daniel' })
  .exec(function (err, user) {
      //
  });

Do đó, khi bạn không chuyển một lệnh gọi lại, bạn có thể tạo một truy vấn và cuối cùng thực thi nó.

Bạn có thể tìm thêm thông tin trong tài liệu mongoose .

CẬP NHẬT

Một điều cần lưu ý khi sử dụng Promises kết hợp với các hoạt động không đồng bộ của Mongoose là các truy vấn Mongoose không phải là Promise. Các truy vấn trả về giá trị có thể , nhưng nếu bạn cần một Lời hứa thực sự, bạn nên sử dụng execphương thức này. Thông tin thêm có thể được tìm thấy ở đây .

Trong quá trình cập nhật, tôi nhận thấy rằng tôi đã không trả lời rõ ràng câu hỏi:

Tôi chưa bao giờ thấy phương pháp đó trong Javascript trước đây? Làm gì chính xác?

không phải là một phương pháp JavaScript gốc, mà là một phần của API Mongoose.


4
Điều gì sẽ xảy ra nếu tôi đã đặt mongoose.Promise = demand ('bluebird'), tôi vẫn cần sử dụng .exec ()? Cảm ơn.
wayofthefuture

4
@wayofthefuture Tôi thấy tài liệu thực sự khó hiểu về vấn đề này, nhưng tôi tin rằng bạn vẫn cần gọi execphương thức. Đây là những gì họ làm trong tài liệu ít nhất. Để chắc chắn bạn có thể kiểm tra chính mình với Model.find() instanceof require('bluebird'). Hi vọng điêu nay co ich.
danillouz

1
Và câu hỏi đặt ra là các thao tác khác như delete và insertMany ... có cần thiết trong những trường hợp này hay không? Xóa sẽ phải sử dụng một số loại truy vấn bên dưới nắp ca-pô ...
wayofthefuture

1
exec cũng trả về một lời hứa, nếu không gọi lại được thông qua, đó là rất thuận tiện tôi phải nói
Alexander Mills

Nó có thể cứu ai đó . Nếu bạn nghĩ rằng Model.update () sẽ thực hiện công việc của nó và không đợi một số dữ liệu không quá quan trọng được cập nhật và trả lại phản hồi cho API; Cập nhật của bạn sẽ không thực thi. Bạn cần Model.update().exec()đảm bảo rằng nó sẽ thực thi. Sau đó, bạn có thể trả lời api mà không cần chờ cập nhật.
Yogesh

48

Daniel đã trả lời điều này khá đẹp. Để xây dựng danh sách đầy đủ các cách tạo và thực thi truy vấn, hãy xem các trường hợp sử dụng sau:

Tòa nhà truy vấn

Mongoose sẽ không thực hiện một truy vấn cho đến khi thenhoặc execđã được gọi đến. Điều này rất hữu ích khi xây dựng các truy vấn phức tạp. Một số ví dụ có thể bao gồm việc sử dụng các hàm populateaggregate.

User.find({name: 'John'}) // Will not execute

Thực thi thông qua gọi lại

Mặc dù nhiều người không thích do tính chất lồng vào nhau, các truy vấn có thể được thực thi bằng cách cung cấp lệnh gọi lại tùy chọn.

User.find({name: 'John'}, (err, res) => {}) // Will execute

Sau đó, API như một lời hứa / A +

Các truy vấn Mongoose cung cấp một thenchức năng. Không nên nhầm lẫn điều này với những lời hứa thông thường. Nói một cách đơn giản, đặc tả Promises / A + yêu cầu một thenhàm hoạt động giống như cách chúng ta đã quen với các lời hứa.

User.find({name: 'John'}).then(); // Will execute
Promise.all([User.find({name: 'John'}), User.find({name: 'Bob'})]) // Will execute all queries in parallel

Hàm thực thi

Từ tài liệu của Mongoose If you need a fully-fledged promise, use the .exec() function.

User.find({name: 'John'}).exec(); // Will execute returning a promise

1
tài liệu không đề cập đến nó một cách rõ ràng nhưng các ví dụ cho thấy User.save () cũng trả về một lời hứa. Ngoài execute () và save (), có phương thức mongoose nào khác trên mô hình trả về một lời hứa không, hay chỉ là hai phương thức này?
thetrystero

Như đã chỉ ra ở trên, bạn cũng có thể sử dụng thentrên một truy vấn để trả về một lời hứa. Điều này không khác nhiều so với exec. Trường hợp sử dụng tôi thấy tiện dụng này là khi sử dụng một cái gì đó như Promise.all. Tuy nhiên, không chắc liệu lời hứa trả về có exechoạt động trong những bối cảnh như vậy hay không.
Anshul Koka

[CÂU TRẢ LỜI ĐƯỢC CHẤP NHẬN]
Cody

Bạn có thể vui lòng thêm một ví dụ hoàn chỉnh với .exec () không? @AnshulKoka Là nó mà các .exec () tự động làm cho không đồng bộ truy vấn hoặc i nên thêm async / chờ đợi
O'Dane Brissett

Làm cho truy vấn không đồng bộ sẽ yêu cầu async / await, vì vậy tôi không chắc mình có hiểu câu hỏi hay không. Chỉ cần tiền tố chờ đợi ví dụ của tôi cho yêu cầu của bạn cho một ví dụ hoàn chỉnh.
Anshul Koka

7

exec()sẽ trả lại một lời hứa nếu không có cuộc gọi lại nào được cung cấp. Vì vậy, mẫu sau rất tiện lợi và chung chung - nó có thể xử lý các lệnh gọi lại hoặc lời hứa một cách độc đáo:

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

}

Tôi khuyên bạn nên sử dụng lời hứa của Bluebird với Mongoose, để làm điều đó, hãy sử dụng lệnh gọi này:

const mongoose = require('mongoose');
mongoose.Promise = require('bluebird');

tại sao chúng ta cần bluebird? khi chúng tôi có hành ()
Indraraj26
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.