简体   繁体   English

按顺序执行多个数据库查询(承诺)

[英]Execute Several database queries (promises) sequentially

The database queries themselves are not the issue - they work fine.数据库查询本身不是问题 - 它们工作正常。

The problem is, I need to execute all of them sequentially:问题是,我需要按顺序执行所有这些:

DELETE FROM myTable;
INSERT INTO myTable(c1, c2, c3) VALUES (x, y, z);
SELECT * FROM myTable;

And I can't figure out how to do that in Node, no matter what I try.而且无论我尝试什么,我都无法弄清楚如何在 Node 中做到这一点。 This question seems to be the most-trafficked solution, and it would have me do something like this (where client is from pg and should be returning promises): 这个问题似乎是访问量最大的解决方案,它会让我做这样的事情( client来自pg ,应该返回承诺):

// client is my database client, has already been initialized
// f is an object corresponding to my database
var res;
Promise.resolve()
      .then(() => {
          console.log("Deleting");
          return client.query("DELETE FROM FileFormat");
      })
      .then(() => {
        console.log("Inserting");
        return client.query("INSERT INTO myTable(c1, c2, c3) VALUES ($1, $2, $3)", [f.x, f.y, f.z]);
      })
      .then(() => {
        console.log("Selecting");
        return client.query("SELECT * FROM FileFormat").then((err, result) => res = result.rows)
      })
      .then(() => {
        console.log("Finished");
        console.log(res);
      })

I would expect it to print Deleting , then Inserting , then Selecting , then Finished , then the data I just inserted into the database.我希望它打印Deleting ,然后是Inserting ,然后是Selecting ,然后是Finished ,然后是我刚刚插入数据库的数据。

Instead, it's printing Deleting and then doing nothing.相反,它正在打印Deleting然后什么也不做。

I don't want to chain client.query.then(client.query.then(...)) infinitely, because that makes my code grow arbitrarily far indented.我不想无限地链接client.query.then(client.query.then(...)) ,因为这会使我的代码任意地缩进。 I would rather keep my code as flat as possible, and execute these calls sequentially, waiting for each one to finish before starting the next.我宁愿让我的代码尽可能平坦,并按顺序执行这些调用,等待每个调用完成后再开始下一个调用。 How do I do that?我怎么做?

Answer from my comments to the original question从我对原始问题的评论中回答

The client might not actually be resolving the promises which would cause this behavior.客户端可能实际上并未解决会导致此行为的承诺。 If you remove all of the client.query you will see that all of the logs are going to look as you expect.如果您删除所有 client.query,您将看到所有日志都将如您所愿。 Your Javascript code is already doing what you want and the problem seems to be with the PG client.您的 Javascript 代码已经在做您想做的事情,问题似乎出在 PG 客户端上。

So I was able to get this to work in my ExpressJS app by following this pattern.所以我能够按照这个模式让它在我的 ExpressJS 应用程序中工作。

Essentially, you initiate a:本质上,您启动了一个:

    try{
      client.query('BEGIN'); 
      // ....do your sequential actions within here.
      client.query('COMMIT'); 
    }catch(e){
      // handle error messaging here
      client.query('ROLLBACK')
    }

For ExpressJS I wrapped mine in an IIFE (not shown above but still in the documents somewhere).对于 ExpressJS,我将我的封装在IIFE中(上面未显示,但仍在某处的文档中)。 so above code would look something like this:所以上面的代码看起来像这样:

   ;(async() => {
     //above code in here.
   })()
   .catch((e)=>{ 
    //do the thing.
   });

the node-postgres guide here . node-postgres 指南在这里 I've pasted the snippet from the site below.我已经从下面的网站粘贴了片段。

     const { Pool } = require('pg')
     const pool = new Pool()
 
     // note: we don't try/catch this because if connecting throws an exception
     // we don't need to dispose of the client (it will be undefined)
     const client = await pool.connect()
 
     try {
       await client.query('BEGIN')
       const queryText = 'INSERT INTO users(name) VALUES($1) RETURNING id'
       const res = await client.query(queryText, ['brianc'])
 
       const insertPhotoText = 'INSERT INTO photos(user_id, photo_url) VALUES ($1, $2)'
       const insertPhotoValues = [res.rows[0].id, 's3.bucket.foo']
       await client.query(insertPhotoText, insertPhotoValues)
       await client.query('COMMIT')
     } catch (e) {
       await client.query('ROLLBACK')
       throw e
     } finally {
       client.release()
     }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM