我是承諾的新手,我試圖在Node.js中使用PostgreSQL中的RSVP承諾,我做錯了,最有可能的。 有關如何解決該問題或如何改進代碼的任何建議,都將受到讚賞。解析承諾數組node.js
我試圖實現的是:在接收數據之後 - 處理數據以創建SQL更新查詢,並在它們準備好時 - 執行它們。這裏的數據是用戶ID的數組。
什麼不起作用:我得到的是沒有解決的承諾數組的數組,我試圖解決該陣列像這樣:
var promise4all = RSVP.all(
updateQueries.map((innerPromiseArray) => {
return RSVP.all(innerPromiseArray);
})
);
promise4all.then((promiseGroupResult) => {
// doesn't get here
});
但它也沒工作。
的代碼:
1)函數,其接收數據,並調用函數 'promiseQuery' 來處理數據 '更新':
const RSVP = require('rsvp');
let db;
const update = (data) => {
let users = {
items: data.user, // data to be updated in db - array of user ids
item_type: 1,
id: data.department
}
let updateQueries = [];
// adding query promises to updateQueries
updateQueries.push(promiseQuery(users.id, users.item_type, users.items));
RSVP.all(updateQueries).then((results) => {
/* here 'results' looks like that:
[ [ { query: 'INSERT INTO link_to_department (item_type, department, item) VALUES ($item_type, $department, $item)',
values: [Object] },
{ query: 'DELETE FROM link_to_department WHERE department = $(department) AND item_type = $(item_type) AND item=$(item)',
values: [Object] } ] ]
db update below fails with '[Empty or undefined query.]'*/
db.tx((trx) => {
let sqlUpdates = [];
results.forEach((query) => {
sqlUpdates.push(trx.none(query.query, query.values))
})
return trx.batch(sqlUpdates);
}).then(() => {
res.sendStatus(204);
}).catch((err) => {
console.log('error', err.message);
// handle errors
});
});
};
2)函數 'promiseQuery' 處理數據(它在分貝接收的數據和數據進行比較用新的數據來更新分貝):
const promiseQuery = (department_id, item_type, items) => {
return new RSVP.Promise((resolve, reject) => {
db.query('SELECT item FROM link_to_department WHERE department=' + department_id + ' AND item_type=' + item_type)
.then((db_items) => {
let promises = [];
let itemsToBeRemoved = [];
let itemsToBeAdded = [];
/* here we have array of user ids we received: 'items'
and array of user ids from db: 'db_items' */
// populating 'itemsToBeAdded' and 'itemsToBeRemoved' with user ids that need to added or removed:
populateUpdateArray(items, db_items, itemsToBeAdded);
populateUpdateArray(db_items, items, itemsToBeRemoved);
let insert_query = 'INSERT INTO link_to_department (item_type, department, item) VALUES ($item_type, $department, $item)'
let delete_query = 'DELETE FROM link_to_department WHERE department = $(department) AND item_type = $(item_type) AND item=$(item)';
// creating update sql queries
populateUpdateQuery(insert_query, itemsToBeAdded, department_id, item_type, promises);
populateUpdateQuery(delete_query, itemsToBeRemoved, department_id, item_type, promises);
RSVP.all(promises).then((results) => {
/* here 'results' looks like this:
[ { query: 'INSERT INTO link_to_department (item_type, department, item) VALUES ($item_type, $department, $item)',
values: { item_type: 19, department: 1, item: '1' } },
{ query: 'DELETE FROM link_to_department WHERE department = $(department) AND item_type = $(item_type) AND item=$(item)',
values: { item_type: 19, department: 1, item: 1 } }] */
return resolve(results);
});
}).catch(() => {
reject();
})
});
};
3)該函數「populateUpdateArray」填充需要被更新的用戶ID的數組(BASI凱莉,接收到的用戶ID應該在DB取代IDS - 爲我們檢查收到什麼ID不以dB爲單位,什麼IDS以dB爲單位是不是在接收IDS):
const populateUpdateArray = (array_0, array_1, updateArray) => {
array_0.forEach((item) => {
if (array_1.indexOf(item) === -1) {
updateArray.push(item);
}
});
};
4)這個函數「populateUpdateQuery '返回sql更新查詢:
const populateUpdateQuery = (query, id_array, department_id, item_type, promises) => {
return new RSVP.Promise((resolve, reject) => {
id_array.forEach((item) => {
let values = {
item_type: item_type,
department: department_id,
item: item
};
promises.push({query, values});
});
resolve(promises);
});
};
謝謝!
編輯:我改變了代碼只有一個數據庫連接,我簡化了一些代碼。我沒有收到任何錯誤,但仍然沒有執行查詢。我想我在這裏缺少一些基本的東西:
const update = (data) => {
let users = {
items: data.user,
item_type: 1,
id: data.department
}
db.tx((tx) => {
let updateQueries = [];
updateQueries.push(promiseQuery(department.id, users.item_type, users.items, tx));
RSVP.all(updateQueries).then((results) => {
// results is array of array, so i flatten it
let sqlUpdates = results.reduce((a, b) => { return a.concat(b); }, []);
/* sqlUpdates here:
[ Promise {
_bitField: 0,
_fulfillmentHandler0: undefined,
_rejectionHandler0: undefined,
_promise0: undefined,
_receiver0: undefined } ]
*/
return tx.batch(sqlUpdates);
});
}).then(() => {
res.sendStatus(204);
}).catch((err) => {
console.log('error', err.message);
});
};
const promiseQuery = (department_id, item_type, items, tx) => {
return new RSVP.Promise((resolve, reject) => {
tx.query('SELECT item FROM belongs_to_departments WHERE department=' + department_id + ' AND item_type=' + item_type)
.then((db_items)=> {
let queries = [];
let itemsToBeAdded = [];
let insert_query = 'INSERT INTO belongs_to_departments (item_type, department, item) VALUES ($(item_type), $(department), $(item))';
populateUpdateArray(items, db_items, itemsToBeAdded);
populateUpdateQuery(insert_query, itemsToBeAdded, department_id, item_type, queries, tx);
resolve(queries);
}).catch(() => {
reject();
});
});
};
const populateUpdateArray = (array_0, array_1, updateArray) => {
array_0.forEach((item) => {
if (array_1.indexOf(item) === -1) {
updateArray.push(item);
}
});
};
const populateUpdateQuery = (query, id_array, department_id, item_type, queries, tx) => {
id_array.forEach((item) => {
let values = {
item_type: item_type,
department: department_id,
item: item
};
queries.push(tx.none(query, values));
});
};
它在下列常見的錯誤解釋:任務與根/直接查詢](https://github.com/vitaly-t/pg-promise/wiki/Common-錯誤#tasks-versus-rootdirect-queries) –
感謝隊友,是不是「正確的方式做到這一點」的鏈接正是我所做的與db.tx(更新)功能(所有插入/刪除查詢)?你的意思是我最好包括1)選擇我在'promiseQuery'和2)所有這些插入/刪除查詢到一個任務/ TX? –
令人困惑的是,爲什麼你的函數'populateUpdateQuery'全部使用promise,而它甚至不是異步的...因此,我們正在從單獨的部分開始工作。一般來說,是的,您應該在單個任務/事務中執行所有查詢。 –