Node.js和MongoDb中同步应用程序的结构

Node.js和MongoDb中同步应用程序的结构,node.js,mongodb,asynchronous,synchronization,Node.js,Mongodb,Asynchronous,Synchronization,我需要构建一个应用程序来完成这些事情(顺序): 如果Node.js是同步的,我可以这样写: var url = 'http://...'; var jsons = []; connectDb('db'); createCollection('db', 'cas'); if(checkForUpdates(url)) { var $ = scrape(url); jsons = elaborate($); for(var i = 0; i < jsons.length

我需要构建一个应用程序来完成这些事情(顺序):

如果Node.js是同步的,我可以这样写:

var url = 'http://...';
var jsons = [];
connectDb('db');
createCollection('db', 'cas');
if(checkForUpdates(url)) {
    var $ = scrape(url);
    jsons = elaborate($);
    for(var i = 0; i < jsons.length; i++) {
        saveDocumentOnDbIfNotExistsYet('db', 'cas', jsons[i]);
    }
}
downloadCollectionToFile('db', 'cas', './output/casData.csv');
createBarChart('./output/casData.csv');
disconnectDb('db');
如果我理解正确,在本例中,执行(如果Node.js是同步的)相当于:

// some code (A)
// some code (E)
if(some code (B) not produce errors) {
    // some code (C)
}
else {
    // some code (D)
}
或者(在代码A和E之间交换,因为它们是异步的)

现在我想知道我的应用程序的正确结构是什么。 我想:

var cheerio = require('cheerio');
var express = require('express');
var fs = require('fs');
var MongoClient = require('mongodb').MongoClient;

var dbUrl = 'mongodb://localhost:27017/';
var dbName = 'db';
var collectionName = 'cas';
const app = express(); // run using > node app.js

// connect to db
var connect = function(url) {
    return new Promise(function(resolve, reject) {
        MongoClient.connect(url + dbName, function(err, db) {
            if(err) {
                reject(err);
            }
            else {
                console.log('Connected');
                resolve(db);
            }
        });
    });
}

// create collection
connect.then(function(db) {
    db.createCollection(collectionName, function(err, res) {
        if(err) {
            throw err;
        }
        else {
            console.log('Collection', collectionName, 'created!');
        }
    });
});

// connection error
connect.catch(function(err) {
    console.log('Error during connection...');
    throw err;
});
是吗?如果是,我如何继续执行其他步骤? 我可以改进我的代码吗

编辑1 按照Аааааааааа的示例,我以这种方式修改了我的代码:

app.js

// my files
var db = require('./middlewares/db.js');

var url = 'mongodb://localhost:27017/';
var dbName = 'db';
var collectionName = 'cas';

const start = async function() {
  const connect = await db.connectToMongoDb(url, dbName);
  const cas = await connect.createYourCollection(collectionName);
  const isPageHasUpdates = oneMoreFunction(); // i don't know how you gonna check it
  if(isPageHasUpdates) {
      await step 4;
      await step 5;
      await step 6;
  }
  await step 7
  return something; // if you want
}

start()
.then(res => console.log(res)) // here you can use result of your start function if you return something or skip this then
.catch(err => console.log(err)); // do something with your error
中间件/db.js

var MongoClient = require('mongodb').MongoClient;
let dbInstance;

var methods = {};

methods.connectToMongoDb = function(url, dbName) {
    if(dbInstance) {
        return dbInstance;
    }
    else {
        MongoClient.connect(url + dbName, function(err, db) {
            if(!err) {
                dbInstance = db;
                return db;
            }
        });
    }
}

methods.createYourCollection = function(collectionName) {
    ?.createCollection(collectionName, function(err, res) {
        if(err) {
            throw err;
        }
    });
}

module.exports = methods;
但我不确定我是否做得很好。
如何在不同的文件中分离函数?例如,我想把所有关于db的函数都放在文件middleware/db.js中。但是我在第
行中遇到了一些问题。createCollection(collectionName,function(err,res)
如果您运行的是node 7.6或更高版本,更好的方法是使用async Wait,它可以与Promissions一起工作

所以你的代码看起来像

const start = async() => {
  const connect = await connectToMongoDb(url);
  const cas = await connect.createYourCollection();
  const isPageHasUpdates = oneMoreFunction(); // i don't know how you gonna check it
  if(isPageHasUpdates) {
      await step 4;
      await step 5;
      await step 6;
  }
  await step 7
  return something; // if you want
}

start()
.then(res => console.log(res)) // here you can use result of your start function if you return something or skip this then
.catch(err => console.log(err)); // do something with your error
确保您将要等待的任何函数都应该像使用connect函数一样得到承诺(但如果您使用的是已经承诺的函数)

更新

最好的方法是使用,但是如果您想使用本机mongodb,您可以这样编写mongodb(只是一个示例)

您可以根据需要扩展此示例

您可以创建函数createCollection

const createCollection = (connection, collectionName) => {
  return connection.createCollection(collectionName); // actually i'm not sure that this function exists in mongodb driver
}
使用方法如下:

const mongodbLib = require('./lib/mongodb'); //path to db.js file
mongodbLib.init()
  .then(connection => mongodbLib.createCollection(connection, 'cas'))
  .then(() => doSmthElse())
或者,如果您确定init已经完成(您可以在启动主脚本(如启动服务器或其他任何操作)之前执行一次)

或者,如果您想像步骤6中那样简单地使用集合,请添加您的cas集合(如示例文件中的用户)。但这也可以在完成init函数时使用。 因此,用法将是

const mongodbLib = require('./lib/mongodb');
const cas = mongodbLib.collections.cas;
cas().insertMany(docs)
  .then()
  .catch()

你能说得更准确一点吗?我试图更改你的代码,但我遇到了问题。我更新了主消息。非常感谢。你的帮助非常有用。你能更好地解释一下这个语法吗?
start()。然后(res=>console.log(res)).catch(err=>console.log(err));
如果我想“正常”编写这段代码的话,我该怎么办?
const createCollection = (connection, collectionName) => {
  return connection.createCollection(collectionName); // actually i'm not sure that this function exists in mongodb driver
}
const mongodbLib = require('./lib/mongodb'); //path to db.js file
mongodbLib.init()
  .then(connection => mongodbLib.createCollection(connection, 'cas'))
  .then(() => doSmthElse())
const mongodbLib = require('./lib/mongodb'); //path to db.js file
const connection = mongodbLib.getConnection();
const mongodbLib = require('./lib/mongodb');
const cas = mongodbLib.collections.cas;
cas().insertMany(docs)
  .then()
  .catch()