Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/383.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 承诺传播中间对象(NodeJS和MongoDB)_Javascript_Node.js_Mongodb_Ecmascript 6_Es6 Promise - Fatal编程技术网

Javascript 承诺传播中间对象(NodeJS和MongoDB)

Javascript 承诺传播中间对象(NodeJS和MongoDB),javascript,node.js,mongodb,ecmascript-6,es6-promise,Javascript,Node.js,Mongodb,Ecmascript 6,Es6 Promise,我试图在Node 4.x中将MongoDB与承诺一起使用 在本例中,我想: 连接到我的mongodb 然后用给定的密钥删除所有内容 然后插入一条记录 然后关闭连接 幸运的是,mongodb客户机在您不回叫它的情况下做出了承诺。这是我想到的 const MongoClient=require('mongodb')。MongoClient; const test=require('assert'); 函数insertDoc(doc,collName){ 返回MongoClient.connect('

我试图在Node 4.x中将MongoDB与承诺一起使用

在本例中,我想:

  • 连接到我的mongodb
  • 然后用给定的密钥删除所有内容
  • 然后插入一条记录
  • 然后关闭连接
  • 幸运的是,mongodb客户机在您不回叫它的情况下做出了承诺。这是我想到的

    const MongoClient=require('mongodb')。MongoClient;
    const test=require('assert');
    函数insertDoc(doc,collName){
    返回MongoClient.connect('mongodb://localhost:27017/myDB')
    。然后(db=>{
    const col=db.collection(collName);
    返回col.deleteMany({'Key':doc.Key})
    .然后(()=>col.insertOne(doc))
    .then(result=>test.equal(1,result.insertedCount))
    .然后(()=>db.close);
    });
    }
    

    代码似乎正常,但嵌套的
    .then()
    “感觉”错误。有什么办法可以在我准备
    .close()
    对象时使用
    db
    对象吗?

    现在,您可以使用外部范围中的变量来实现这一点:

    let db;
    
    function insertDoc(doc, collName) {
      return MongoClient.connect(dsn)
        .then(connectedDb => {
          db = connectedDb;
          return col.deleteMany(doc)
        }) // now you can chain `.then` and still use `db`
    }
    
    有几种可能的替代方法,比如传递
    db
    ,但这对我来说似乎很奇怪。如果希望保持此流,但仍然利用异步性,可以使用
    async
    /
    wait
    。现在,您需要一个transpiler(如babel)和类似于再生器运行时的东西来使用它

    async function insertDoc(doc, collName) {
      const db = await MongoClient.connect(dsn);
      const col = db.collection(collName);
      await col.deleteMany({Key: doc.key});
      const result = await col.insertOne(doc);
      await test.equal(1, result.insertedCount) // is this asynchronous?
      return db.close();
    }
    

    您也可以使用/
    yield
    来避免传输,尽管它有点冗长。

    我发现您必须的是我见过的最具可读性的替代模式。我自己使用缩进(嵌套
    。然后
    )来访问以前的值(这是我唯一一次这么做!)

    很多事情最终会影响代码的外观和读取。以您的
    col
    temporary为例。如果不需要,您的代码可能如下所示:

    var insertDoc = (doc, collName) => MongoClient.connect('mongodb://localhost:x/DB')
      .then(db => db.collection(collName).deleteMany({ 'Key': doc.key })
        .then(() => db.collection(collName).insertOne(doc))
        .then(result => test.equal(1, result.insertedCount))
        .then(() => db.close))
      .then(() => doSomethingElse());
    
    注意
    db.close)之后的额外
    。括号匹配的编辑器很有用。:)

    我不是为了代码的美观而建议删除
    col
    。我之所以显示它,是因为我认为它突出显示了缩进如何很好地显示
    db
    值的范围。当我看到这样的代码时,我开始喜欢这种模式


    在现实生活中,代码并不总是整齐地折叠,但我喜欢这样一种模式,它可以在可能的情况下折叠。

    一种选择是将承诺更多地视为价值,然后在需要时取出包装好的价值。但它也有其可读性的缺点

    e、 g


    我有时会做第一个,但它不是很干净的范围。它可能有一些副作用,比如
    db
    在它应该被垃圾收集后仍然存在。在可读性方面,我有时会使用它,但我发现称它为
    haveDb
    是有益的,可以将它与它的值区分开来。e、 g.
    haveDb.then(db=>{})
    。就像“当我有db的时候,就用它来做这个”。很好。我喜欢这个比我刚才做的稍微好一点你的代码和嵌套的
    then
    s没有问题(除了你应该使用
    finally
    not
    then
    作为
    close
    回调)@Bergi没有
    。es6中有没有最后的
    ,但是你仍然需要它的功能来关闭
    @Bergi
    。然后(()=>db.close(),e=>(db.close(),Promise.reject(e))
    或者类似的东西,同意。
    function insertDoc(doc, collName) {
      const db = MongoClient.connect('mongodb://localhost:27017/myDB');
      const col = db.then(db => db.collection(collName));
    
      return col.deleteMany({ 'Key': doc.key })
        .then(() => col.insertOne(doc))
        .then(result => test.equal(1, result.insertedCount))
        // You've still got the 'db' promise here, so you can get its value
        // to close it.
        .then(() => db.then(db => db.close()));
    }