Using Async/Await with Mongoose

Queries in Mongoose 4.x have a .then() function, so you don't need any extra work to use mongoose with async/await:

const mongoose = require('mongoose');
async function run() {
  // No need to `await` on this, mongoose 4 handles connection buffering
  // internally
  mongoose.connect('mongodb://localhost:27017/test');
  await mongoose.connection.dropDatabase();
  const MyModel = mongoose.model('Test', new mongoose.Schema({ name: String }));
  await MyModel.create({ name: 'Val' });
  // Prints an array with 1 element, the above document
  console.log(await MyModel.find());
}
run().catch(error => console.error(error.stack));

Async/await makes interacting with mongoose cursors much more elegant. While you still can use cursors as a stream with async/await, it's much more elegant to use the next() function. Fundamentally, a mongoose cursor is an object with a next() function that returns a promise which resolves to the next document in the query result, or null if there are no more documents.

const mongoose = require('mongoose');
async function run() {
  mongoose.connect('mongodb://localhost:27017/test');
  await mongoose.connection.dropDatabase();
  const MyModel = mongoose.model('Test', new mongoose.Schema({ name: String }));
  await MyModel.create({ name: 'Val' }, { name: 'Varun' });
  // A cursor has a `.next()` function that returns a promise. The promise
  // will resolve to the next doc if there is one, or null if they are no
  // more results.
  const cursor = MyModel.find().sort({name: 1 }).cursor();
  for (let doc = await cursor.next(); doc != null; doc = await cursor.next()) {
    // Prints "Val" followed by "Varun"
    console.log(doc.name);
  }
}
run().catch(error => console.error(error.stack));

Mongoose cursors also have a neat eachAsync() function that lets you do some rudimentary functional programming with async/await. The eachAsync() function executes a (potentially async) function for each document that the cursor returns. If that function returns a promise, it will wait for that promise to resolve before getting the next document. This is the easiest way to exhaust a cursor in mongoose.

const mongoose = require('mongoose');
async function run() {
  mongoose.connect('mongodb://localhost:27017/test');
  await mongoose.connection.dropDatabase();
  const MyModel = mongoose.model('Test', new mongoose.Schema({ name: String }));
  await MyModel.create({ name: 'Val' }, { name: 'Varun' });
  // A cursor has a `.next()` function that returns a promise. The promise
  // will resolve to the next doc if there is one, or null if they are no
  // more results.
  const cursor = MyModel.find().sort({name: 1 }).cursor();
  let count = 0;
  console.log(new Date());
  await cursor.eachAsync(async function(doc) {
    // Wait 1 second before printing first doc, and 0.5 before printing 2nd
    await new Promise(resolve => setTimeout(() => resolve(), 1000 - 500 * (count++)));
    console.log(new Date(), doc);
  });
}
run().catch(error => console.error(error.stack));

你可能感兴趣的:(Using Async/Await with Mongoose)