mysql - Node.js 从一个函数返回一个 promise

标签 mysql node.js promise

我正在探索 node.js 中 promise 和回调的可能性 我试图找到一种方法让这段代码起作用。目前我面临的问题是,当我调用一个函数并想使用返回值时,它还没有准备好。我知道我必须做什么,但不知道怎么做。基本上,我必须让 insertAddress() 返回一个 promise (这样我就可以在其上使用 .then() ),或者将回调作为参数。为此,我还认为 databaseWork() 应该返回一个 promise 。但我不知道在哪里添加它。 该问题位于“console.log(out)”中,它在设置 out 变量之前运行(因为 insertAddress 仍在运行)。 这是我的代码

app.js
-----

const databaseWork = require('./db/mysql.js').databaseWork;

app.use('/test',  (req, resp) => {
  var address = {
     country : "Country",
     city : "Randomcity",
     street : "Random",
     number : 6,
     postalcode : "A789",
     province : "a province"
   }
  var out = insertAddress(address);  //<== takes time to finish, is not ready when the next console.log finishes
  console.log(out);
});

function insertAddress(address){
    var rows
    databaseWork(
      //Following anonymous function contains the actual workload. That has to be done inside a transaction
       async (connection) => {
       rows = await insertAddressQuery(address,connection);
       console.log(rows); //this one waits for insertAddressQuery to be complete
    })
    return rows; //this will run before insertAddressQuery is complete
}


function insertAddressQuery(address,connection) {
    return new Promise( (resolve, reject) => {
    //async job
      connection.query('INSERT INTO address (country,city,Street,number,postalcode,province) VALUES(?,?,?,?,?,?)', [address.country,'4','5',6,'7','8'] , (err, rows) => {
            if (err) {reject(err);}
              resolve(rows);
        });
    });
};


/db/mysql.js
------------

var mysql = require('mysql');
var dbpool = mysql.createPool({
  host: process.env.HOST_DB,
  user: process.env.USER_DB,
  password: process.env.PWD_DB,
  database: process.env.DB
});

function databaseWork(workload){
  dbpool.getConnection( async (err, connection) => {
      await beginTransaction(connection);

      await workload(connection);

      await commitTransaction(connection)
      connection.release();
    });
}


function beginTransaction(connection){
  return new Promise( (resolve, reject) => {
    //async job
    connection.beginTransaction( (err) => {
      if (err) {reject(err);}
        resolve();
    });
  });
};



function commitTransaction(connection) {
    return new Promise( (resolve, reject) => {
    //async job
    connection.commit( (err) => {
        if (err) {reject(err);}
          resolve();
        });
    });
};

exports.databaseWork = databaseWork;

最佳答案

你会在你的databaseWork中这样做:

function databaseWork(workload) {
  return new Promise((resolve, reject) => {
    dbpool.getConnection(async (err, connection) => {
      try {
        await beginTransaction(connection);

        var result = await workload(connection);

        await commitTransaction(connection)

        resolve(result);
      } catch( err ) {
         reject(err)
      } finally {
        connection.release();
      }
    });
  })

}

databaseWork 返回的Promise 将由workload 的结果解析。现在您可以将 insertAddress 更改为:

async function insertAddress(address){
    return databaseWork(connection => {
       return insertAddressQuery(address,connection);
    })
}

然后您需要将路由更改为:

app.use('/test', async (req, resp) => {
  var address = {
    country: "Country",
    city: "Randomcity",
    street: "Random",
    number: 6,
    postalcode: "A789",
    province: "a province"
  }
  var out = await insertAddress(address); // use await here to wait for insertAddress to be finished

  console.log(out);
});

*UPDATE 代码,带有返回 Promise 的 getConnection 函数:

function getConnection() {
  return new Promise((resolve, reject) => {
    dbpool.getConnection((err, connection) => {
      if (err) {
        reject(err)
      } else {
        resolve(connection);
      }
    })
  });
}

async function databaseWork(workload) {
  var connection = await getConnection();
  var result;
  try {
    await beginTransaction(connection)

    result = await workload(connection)

    await commitTransaction(connection)
  } catch (err) {
    // a rollback might be neccesaary at that place
    throw err
  } finally {
    connection.release();
  }

  return result;
}

关于mysql - Node.js 从一个函数返回一个 promise,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49655570/

相关文章:

javascript - Node.js 中的 SetTimeout 问题

node.js - 如何在 Jade 中包含一个css文件(不链接它)

php - 点击时如何查询MYSQL?

php - 不从购物车中删除项目

Azure 上的 Node.js 集群 : ENOTSUP - cannot write to IPC channel

javascript - 异步完成后如何执行另一个功能?

javascript - 如何让 JavaScript Promise 等待另一个 Promise 在 for() 循环中得到解决

javascript - Promise.all 找到哪个 promise 被拒绝

python - 缺少 mysql.sock;产生 OperationalError : (2002, "Can' t 通过套接字 '/tmp/mysql.sock' (2)"连接到本地 MySQL 服务器"

mysql - 如何在 MySQL 中获取当前的舍入时间?