/ / Използване на цикли и обещания при транзакции в Sequelize - javascript, node.js, express, promise, sequelize.js

Използване на цикли и обещания в транзакциите в Sequelize - javascript, node.js, express, promise, sequelize.js

Понастоящем изграждам приложение Nodejs, Express, Sequelize (с PostgreSQL) и имам няколко проблема с използването на обещания заедно с транзакции и цикли.

Опитвам се да разбера как да използвам за зареждане в транзакция. Опитвам се да пресекам списък от членове и да създам нов потребител в базата данни за всеки от тях.

Знам, че следният код е грешен, но показва какво се опитвам да направя.

Може ли някой да ме насочи в правилната посока?

        var members = req.body.members;
models.sequelize.transaction(function (t) {
for (var i = 0; i < members.length; i++) {
return models.User.create({"firstname":members[i], "email":members[i], "pending":true}, {transaction: t}).then(function(user) {
return user.addInvitations([group], {transaction: t}).then(function(){}).catch(function(err){return next(err);});
})
};
}).then(function (result) {
console.log("YAY");
}).catch(function (err) {
console.log("NO!!!");
return next(err);
});

Отговори:

23 за отговор № 1

Трябва да използвате a Promise.all

    var members = req.body.members;
models.sequelize.transaction(function (t) {
var promises = []
for (var i = 0; i < members.length; i++) {
var newPromise = models.User.create({"firstname":members[i], "email":members[i], "pending":true}, {transaction: t});
promises.push(newPromise);
};
return Promise.all(promises).then(function(users) {
var userPromises = [];
for (var i = 0; i < users.length; i++) {
userPromises.push(users[i].addInvitations([group], {transaction: t});
}
return Promise.all(userPromises);
});
}).then(function (result) {
console.log("YAY");
}).catch(function (err) {
console.log("NO!!!");
return next(err);
});

Не вярвам, че трябва catch в рамките на продължаването на транзакциите, както мисля, че прескочи на улова по сделката

Съжалявам за форматирането. По мобилния телефон.

Promise.all ще изчака всички обещания да се върнат (или да се провалят) преди да стартират .then и .then обратното набиране ще бъде всички обещаващи данни от всеки масив


5 за отговор № 2

Трябва да използвате вградените конструктивни структури на синята птица, които корабите продължават:

var members = req.body.members;
models.sequelize.transaction(t =>
Promise.map(members, m => // create all users
models.User.create({firstname: m, email: m, "pending":true}, {transaction: t})
).map(user => // then for each user add the invitation
user.addInvitations([group], {transaction: t}) // add invitations
)).nodeify(err); // convert to node err-back syntax for express

1 за отговор № 3

В зависимост от внедряването на Node.js това може да помогне. Имам една и съща настройка, използвайки експресни, POSTGRES и продължаване.

Лично аз предпочитам изпълнението на async / await (ES6) след това / улова, тъй като е по-лесно да се чете. Също така, създаването на функция, която може да се нарече външно подобрява повторната употреба.

async function createMemeber(req) {
let members = req.body.members;
for (var i = 0; i < members.length; i++) {
// Must be defined inside loop but outside the try to reset for each new member;
let transaction = models.sequelize.transaction();
try {
// Start transaction block.
let user = await models.User.create({"firstname":members[i],  "email":members[i], "pending":true}, {transaction});
await user.addInvitations([group], {transaction}));

// if successful commit the record. Else in the catch block rollback the record.
transaction.commit();
// End transaction block.
return user;
} catch (error) {
console.log("An unexpected error occurred creating user record: ", error);
transaction.rollback();
// Throw the error back to the caller and handle it there. i.e. the called express route.
throw error;
}
}
}

0 за отговор № 4

Първо: https://caolan.github.io/async/docs.html

Така лесно:

// requiring...
const async = require("async");

// exports...
createAllAsync: (array, transaction) => {
return new Promise((resolve, reject) => {
var results = [];
async.forEachOf(array, (elem, index, callback) => {
results.push(models.Model.create(elem, {transaction}));
callback();
}, err => {
if (err) {
reject(err);
}
else {
resolve(results);
}
});
});
}