首页 > 解决方案 > 使用 Promise 的同步数据库查询

问题描述

如果我遗漏了一些微不足道的东西,我深表歉意。我想要做的是同步调用数据库查询。在进行下一步之前,我需要确保数据库插入已完成。我也不想嵌套在回调中。我正在尝试使用承诺,但它似乎没有像我预期的那样工作。这是我的代码:

async init()
{
        await this.initWalletTable();
}


async initWalletTable()
{
   console.log("Creating wallet table");
   var self = this;
   walletParams.wallets.forEach(function(wallet) {

   (async() => {
         await self.insertWallet(wallet); 
         console.log("inserted " + wallet.multisig_wallet_name);
         })();
      });
 }


 insertWallet(wallet)
 {
      console.log("Inserting wallet " + wallet.multisig_wallet_name);
      return new Promise((resolve, reject) => {

            pool.query(`INSERT INTO ${schema}wallet \
                        (name, wallet_name_1, ) \
                        VALUES ($1, $2) \
                        ON CONFLICT (name) DO NOTHING`, [wallet.multisig_wallet_name, wallet.wallet_name1])
            .then(dbres => {
                return resolve(true);
            })
            .catch(e => {
                console.error(e.stack);
               return  resolve(true);
            })

        });
    }

标签: node.jspromiseasync-await

解决方案


我认为我在下面列出的解决方案可以解决您的问题。

我想要做的是同步调用数据库查询。在进行下一步之前,我需要确保数据库插入已完成。我也不想嵌套在回调中。

我不确定你在问什么。我想我知道你的意思,我试图解决你的问题,但如果我不理解你的意图,请告诉我。需要澄清的几点:

  • Promise 旨在使异步代码更易于维护和理解(而不是嵌套函数)。
  • async/await在此之上构建,使您可以轻松编写同步外观的代码
  • 这个看起来异步的代码仍然在底层使用 Promise,它在底层使用回调。
  • 您希望您的方法是异步的,尤其是因为这是数据库 io。

您要求让您的异步代码串行运行,而不是同时运行。

所做的更改

  • insertWallet方法中,因为pool.query()已经返回了一个 Promise,所以你不需要将它包装在一个显式的 Promise 中。
  • 我不确定你为什么将异步匿名函数包装在内部的立即调用函数表达式中initWalletTable(),但我认为如果你删除那个块你会没事的。

代码

class Wallet {
  constructor(walletParams) {
    this.walletParams = walletParams;
    this.initialized = this.init();
  }

  async init() {
    return await this.initWalletTable();
  }

  async initWalletTable() {
    console.log("Creating wallet table");
    this.walletParams.wallets.forEach((wallet) => {
      await this.insertWallet(wallet);
      console.log("inserted " + wallet.multisig_wallet_name);
    });
  }

  async insertWallet(wallet) {
    console.log("Inserting wallet " + wallet.multisig_wallet_name);
    return pool.query(`INSERT INTO ${schema}wallet \
                        (name, wallet_name_1, ) \
                        VALUES ($1, $2) \
                        ON CONFLICT (name) DO NOTHING`, [wallet.multisig_wallet_name, wallet.wallet_name1])
      .catch(e => {
        console.error(e.stack);
        throw e; // re-raise error
      });
  }
}

推荐阅读