0

を使用して、文字列内の一部のテキストをデータベースの値に置き換えたいと考えています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当然のことながら、空の文字列です。データベースからの値を「待機」するようにこのブロックを書き換える方法はありますか?


私がやろうとしているのは、ユーザーに送信されるメッセージのプレースホルダーを置き換えることです。したがって、上記は呼び出された関数の一部であり、socket.ioprepareMessageを使用してユーザーにメッセージを送信するので、次のようになります。

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

4

1 に答える 1

0

いくつか読んでさらに考えた後、他の誰かが同様の問題を抱えている場合に追加したい解決策を思いつきました。

(上記の質問に加えて、メッセージが文字列の配列であり、順序が維持されるという複雑な問題がありました。)

重要なのは、タスクを使用してすべてのクエリを 1 つのパッケージとして DB に送信し、すべての結果が返されるのを待つことでした。これにより、次のコードが生成されました。

// 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 ...
      });
于 2016-11-03T09:05:45.960 に答える