同步承诺以初始化MongoDB数据库

时间:2018-12-04 22:13:01

标签: node.js mongodb asynchronous

我是Web开发的新手,但鉴于以下代码,我对MongoDB和Nodejs驱动程序有疑问:

<ul class="notifications">
    {% for notice in notifications %}
    <div class="alert alert-block alert-{{ notice.level }}">
        <a class="close pull-right" href="{% url 'notifications:mark_as_read' notice.slug %}">
            <i class="icon-close"></i>
        </a>

        <h4>
            <i class="icon-mail{% if notice.unread %}-alt{% endif %}"></i>
            {{ notice.actor }}
            {{ notice.verb }}
            {% if notice.target %}
            of {{ notice.target }}
            {% endif %}
        </h4>

        <p>{{ notice.timesince }} ago</p>

        <p>{{ notice.description|linebreaksbr }}</p>

        <div class="notice-actions">
            {% for action in notice.data.actions %}
            <a class="btn" href="{{ action.href }}">{{ action.title }}</a>
            {% endfor %}
        </div>
    </div>
    {% endfor %}
</ul>

我想实现这些目标:

  1. 删除数据库
  2. 在拖放后创建数据库并填充数据库
  3. 关闭连接

所有这些目标都在我运行函数时实现,但我认为代码有问题:

  • 运行let MongoClient = require('mongodb').MongoClient; const url = MY_URL; const dbConnected = MongoClient.connect(url); let dbInit = function (){ dbConnected.then( (client) => { let db = client.db('DB_NAME'); db.dropDatabase() .then( () => {}) .catch( err => { throw err;}) return client; } ) .then( (client) =>{ let db = client.db('knodels'); db.collection('Users').insertMany([ //data ]) .then( () => {}) .catch( err => { throw err;}) return client; } ) .then( (client) =>{ client.close(); } ) .catch((err) => {throw err;}) } 时会抛出一些dbInit()
  • 我猜那些必须异步的诺言的同步肯定有些时髦
  • 捕获错误是在最后还是对所有承诺都完成?
  • 关闭客户端连接的承诺

1 个答案:

答案 0 :(得分:0)

让我们命名一些代码段,

let dbInit =  function (){
dbConnected.then(
    (client) => {
        //////////////////////TASK 1/////////////////////
        let db = client.db('DB_NAME');
        db.dropDatabase()
            .then( () => {})
            .catch( err => { throw err;})
        return client;
       //////////////////////TASK 1/////////////////////
    }
)
.then(
    (client) =>{
        //////////////////////TASK 2/////////////////////
        let db = client.db('knodels');
        db.collection('Users').insertMany([
            //data
        ])
        .then( () => {})
        .catch( err => { throw err;})
        return client;
        //////////////////////TASK 2/////////////////////
   }
)
.then(
    (client) =>{            
        client.close();
    }
)
.catch((err) => {throw err;})
}

在一个promise链中,像上面的一个那样,一旦解决了前任问题,就会执行then块。 这意味着包含TASK 2的then块只会在TASK 1完成后执行。

但是,由于您不是TASK 1返回承诺,而是返回真实值(变量客户端),并且由于真实值被视为承诺解析。它甚至可能会在删除完成之前开始执行db.collection('Users').insertMany...

类似的情况适用于下一个then块,在插入完成之前将调用client.close。

因此,与其返回客户端,不如返回db操作,一个promise,它将使链顺序化。

您也不需要这样的嵌套链,每个承诺都有收获,

let connection = null;
dbConnected.then((client) => {
  connection = client;  
  const db = client.db('DB_NAME');
  return db.dropDatabase()
}).then(() => {
  // Perform insert and return a promise//
}).then(() => {
  return connection.close();
}).catch((err) => {
   // handle error //
})

应该做这份工作!