私のdbクエリを私の約束ベース関数と同期させるにはどうすればいいですか?私のコードでは、3つの異なる関数の中で3つのdb演算を実行しています。これは、滝モデルのように順番に実行する必要があります。関数はウォーターフォールモデルで実行されていますが、これらの関数内のdbクエリは非同期で動作しています。これらの関数内でdbクエリを同期して実行する必要があります。私のdbクエリを私の約束ベースの関数と同期させる
1
2
3
4
しかし、私は
1
3
2
4
コードを取得しています:
は、この例では、私は、コンソールに期待していますが、ここでものを過度に複雑さconst Promise = require('bluebird');
// DB Settings
const dbConfig = {
user: process.env.DBUSER,
password: process.env.DBPWD,
database: process.env.DBNAME,
host: process.env.DBHOST,
port: process.env.DBPORT,
poolSize: 10, // max number of clients in the pool
//poolIdleTimeout: 30000, // how long a client is allowed to remain idle before being closed
//reapIntervalMillis: 1000 //frequency to check for idle clients within the client pool
};
const pgp = require('pg-promise')();
const db = pgp(dbConfig);
var currentStatus = '',newStatus = '';
const _updateCurrentStatus =() => new Promise((resolve, reject) => {
const _getCurrentStatus = (_userId) => new Promise((_resolve, _reject) => {
console.log("1");
let statusQuery = "SELECT status FROM users WHERE id=" + _userId;
db.one(statusQuery).then(function (data) {
console.log("2");
currentStatus = data.status;
_resolve();
}).catch(function (error) {
_reject(error);
});
});
const _setUpdateStatus = (cStatus, nStatus) => new Promise((_resolve, _reject) => {
if(allApproved){
if(cStatus == 'nvd_pending'){
//nStatus = 'finance_pending';
newStatus = 'finance_pending';
}else if(cStatus == 'finance_pending'){
//nStatus = 'oracle_pending';
newStatus = 'oracle_pending';
}else if(cStatus == 'oracle_pending'){
//nStatus = 'active';
newStatus = 'active';
}else{
//nStatus = cStatus;
newStatus = cStatus;
}
}else{
//nStatus = 'nvd_pending';
newStatus = 'nvd_pending';
}
//_resolve(nStatus);
_resolve();
});
const _updateStatus = (_newStatus, _payLoad) => new Promise((_resolve, _reject) => {
console.log("3");
let updateuserQuery = "UPDATE users SET status = '"+ _newStatus + "' WHERE id=" + _payLoad.user_id;
let updatePanQuery = "UPDATE user_documents SET status = '" + _payLoad.panstatus + "' WHERE id= " + _payLoad.panid + " AND user_id=" + _payLoad.user_id;
let updateFinanceQuery = "UPDATE user_finance_details SET status = '" + _payLoad.financestatus +" 'WHERE id= " + _payLoad.financeid + " AND user_id=" + _payLoad.user_id;
db.tx(function (t) {
console.log("4");
// `t` and `this` here are the same;
// this.ctx = transaction config + state context;
return t.batch([
t.none(updateuserQuery),
t.none(updatePanQuery),
t.none(updateFinanceQuery)
]);
}).then(function (data) {
_resolve(data);
}).catch(function (error) {
_reject(error);
});
});
_getCurrentStatus(payLoad.user_id)
.then(_setUpdateStatus)
.then(_updateStatus(newStatus, payLoad))
.then(values => {
resolve(values);
},error => {
reject(error);
})
.catch((error) => reject(error));
});
「同期」と言うとき、「シリアルに」という意味ですか? '.then()'と一緒に連鎖するだけでいいです。約束事を同期して実行することはできません。 – Jacob
はい、私は鎖を意味します。この現在の例では、現在のステータスに基づいてユーザーの現在のステータスを取得することになり、ユーザーは新しいステータスを取得し、ステータスは更新されます。 問題はdb部分です。それは事を非同期にし、私の約束関数はdb結果を待たずに戻ります。 – pkd
話題にはなりませんが重要ですが、パラメータ化されたクエリを使用する代わりに、文字列連結によってSQLを構築しています。したがって、コードがSQLインジェクション攻撃に対して脆弱になる可能性があります。私はPostgreSQLのエキスパートではありませんが、この問題を解決するには[PREPARE'dステートメント](https://www.postgresql.org/docs/9.2/static/sql-prepare.html)をご覧ください。 – stakx