Array of queries for `for await` loop for postgresql transaction helper

半世苍凉 提交于 2019-12-13 04:10:20

问题


I made a transaction function that simplifies this action for me like this (it working):

export async function transaction(queriesRaw) {
  let allResults = []

  const client = await pool.connect()

  try {
    await client.query('BEGIN')
    var queries = queriesRaw.map(q => {
      return client.query(q[0], q[1])
    })

    for await (const oneResult of queries) {
      allResults.push(oneResult)
    }
    await client.query('COMMIT')
  } catch (err) {
    await client.query('ROLLBACK')
  } finally {
    client.release()
    return allResults
  }
}

And do transactions like this:

let results = await transaction([
            ['UPDATE readers SET cookies=5 WHERE id=$1;', [1]],
            ['INSERT INTO rewards (id) VALUES ($1);', [3]]
          ])

Transaction should do queries one at a time in array index sequence (so rollback to previos values will work correctly) and return in the same order (sometimes i need return values from some queries)

As i understand it starts already in map map function. In for await i just wait for results of it and second query may complete faster that previos.

So how can i fix this?

P.S. Maybe something like new Promise() instead map is the rigth way?


回答1:


If i got you correctly, Just use a for loop with proper await, instead of a callback style loop.

So you can wait with the function to return unil everything is chronologically executed, With some thinking, you can easily add aa revoke() function or something..


...
export async function transaction(queriesRaw) {
  let allResults = []

  const client = await pool.connect()

  try {
    await client.query('BEGIN')

    for(var i = 0; i < queriesRaw.length;i++) {
        var res = await client.query(queriesRaw[i][0], queriesRaw[i][1])
        allResults.push(res)
    }

    await client.query('COMMIT')
  } catch (err) {
    await client.query('ROLLBACK') 

    // do you maybe wanna errors to results to?
    // allResults.push(err)
  } finally {
    client.release()
    return allResults
  }
}

Info,

Have a look at for example async module, or something similar. So you will not have to think about things like this.




回答2:


Change this:

var queries = queriesRaw.map(q => {
  return client.query(q[0], q[1])
})

for await (const oneResult of queries) {
  allResults.push(oneResult)
}

To:

for(const q of rawQueries) {
   let result = await client.query(q[0], q[1]);
   allResults.push(result);
});


来源:https://stackoverflow.com/questions/56245587/array-of-queries-for-for-await-loop-for-postgresql-transaction-helper

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!