用pg-promise

时间:2016-10-26 11:33:38

标签: node.js pg-promise

我想使用pg-promise将数据库中的某些文本替换为数据库中的值。由于我之前没有使用 Promise ,我正在努力解决如何以最佳方式处理它。

到目前为止,我尝试将同步和异步编程结合起来并不起作用:

var uid = ...;
"Some string".replace(/\#\{([\w]*?)\}/gmi, function(m, c) {
    var r = "";
    db.one("SELECT a FROM ... WHERE x = $1 AND y = $2", [c, uid])
        .then(function(data) {
            r = data.a;
        });
    return r;
});
不出所料,

r是一个空字符串。有没有办法将此块重写为"等待"对于数据库中的值?

我尝试做的是,在发送给用户的消息中替换占位符。所以上面是一个名为prepareMessage的函数的一部分,我使用 socket.io 将消息发送给用户,所以它看起来像这样:

io.to(socket.id).emit('message', { text: prepareMessage(msg) });

1 个答案:

答案 0 :(得分:0)

经过一番阅读和思考后,我提出了一个解决方案,如果其他人遇到类似问题,我想补充一下。

(除了上面的问题,我还有一个额外的复杂因素,即我的消息是一个字符串数组,并且要保留订单。)

关键是使用tasks将所有查询作为一个包发送到数据库,并等待所有结果返回。这导致了以下代码:

// Sample data
var messages = ["String 1 with no placeholder.",
"String 2, #{placeholder1}, String 2.2.",
"String 3 with some more #{placeholder2}."];

// Collect all matches in array
var matches = [];
messages.forEach(function(text, index) {
  const regex = /\#\{([\w]*?)\}/gmi;
  var m;
  do {
    matches.push(regex.exec(text))
  } while(m);
});

// Request data from the database
db.task(function(t) {
  return t.batch(matches.map(function(m) {
    return t.oneOrNone("SELECT ... FROM ... WHERE id = $1", [m[1]])
  }));
})
.then(function(r) {
        // Replace all occurrences of placeholders
        r.forEach(function(p) {
          messages = messages.map(function(t) { return t.replace("#{"+p.id+"}", p.replacement); });
        });

        // Send message to user
        io.emit('text', messages)M
      })
.catch(function(e) {
        // ... error handling ...
      });