gpt4 book ai didi

javascript - 如何链接 Sequelize model.create() promise 以便它们按顺序执行?

转载 作者:行者123 更新时间:2023-12-03 22:19:32 27 4
gpt4 key购买 nike

我对 Node ORM 库 Sequelize 有一个有趣的问题。我希望将此数据插入到一个空表中:

[
{ title: 'Expenditure 1', amount: 100 },
{ title: 'Expenditure 2', amount: 200 },
{ title: 'Expenditure 3', amount: 300 },
{ title: 'Expenditure 4', amount: 400 },
{ title: 'Expenditure 5', amount: 500 },
{ title: 'Expenditure 6', amount: 600 },
{ title: 'Expenditure 7', amount: 700 },
{ title: 'Expenditure 8', amount: 800 },
{ title: 'Expenditure 9', amount: 900 },
{ title: 'Expenditure 10', amount: 1000 },
{ title: 'Expenditure 11', amount: 1100 },
{ title: 'Expenditure 12', amount: 1200 },
{ title: 'Expenditure 13', amount: 1300 },
{ title: 'Expenditure 14', amount: 1400 },
{ title: 'Expenditure 15', amount: 1500 },
{ title: 'Expenditure 16', amount: 1600 },
{ title: 'Expenditure 17', amount: 1700 },
{ title: 'Expenditure 18', amount: 1800 },
{ title: 'Expenditure 19', amount: 1900 },
{ title: 'Expenditure 20', amount: 2000 }
]

正如人们所料,在一个新表中,这些将被赋予 id 值 1、2、3 等,按升序排列。所以我第一次尝试写这些是这样的:
  const writeToTable = (model, rows) => {
let promises = rows.map((row) => model.create(row));
return Promise.all(promises);
}

好吧,它有点工作,但行以不可预测的顺序插入,因为 Promise.all 并行运行 promise ,或者至少不保证按顺序运行它们。

所以我接下来尝试了这个(使用一些代码 from this answer ):
  const writeToTable = (model, rows) => {
let promises = rows.map((row) => model.create(row));
let chain;

for (let i in promises) {
if (chain) chain = chain.then(() => promises[i]);
if (!chain) chain = promises[0];
}

return chain;
}

看起来它必须按顺序运行项目,但不是 - 多次运行代码会产生不同的结果。奇怪的!

所以我接下来试试这个:
  const writeToTable = async (model, rows) => {
let promises = rows.map((row) => model.create(row));

for (let promise of promises) {
await promise;
}
};

这是异步的,没有返回值,所以应该自动返回一个 Promise,一旦所有内部等待的调用都解决了就解决了。但是,不 - 我仍然偶尔会得到错误排序的行。

我可以使用什么技术来确保我的调用按顺序执行?我怀疑 Sequelize 在这里做了一些缓存/后期写入,并让自己陷入困境。我很高兴听到 Sequelize 中的方法可以将整个数组插入,但这感觉有点像作弊 - 我想知道我是否想了解为什么会失败。

我绝对确定源数组是正确的。

在调用服务和运行断言之前,了解这些调用是在 Jest 中进行以设置测试数据可能会有所帮助。

最佳答案

一旦 Promise 被创建,无论 Promise 的解析如何等待,它里面的操作都会运行到最后。例如:

const prom1 = makeProm1();
const prom2 = makeProm2();

在这一点上,Promises 已经开始,并且会做任何他们应该做的事情(并行),即使你稍后单独 await 它们:
await prom1;
await prom2;

const makeProm = num => new Promise(
resolve => setTimeout(
() => {
console.log(num + ' resolving');
resolve();
},
Math.random() * 1000
)
);

(async () => {
const prom1 = makeProm(1);
const prom2 = makeProm(2);
await prom1;
await prom2;
console.log('Done');
})();


这就是你的每个片段正在做的 - .map 立即为 rows 数组的每个项目创建一个新的 Promise,所以无论你之后做什么都不会影响这些 Promise 解析的顺序。

您需要更改一些内容,以便仅在您准备好开始执行 Promise 时才创建 Promise - 也就是说,仅在前一个 Promise 完成执行之后:
const writeToTable = (model, rows) => {
for (const row of rows) {
await model.create(row);
}
}

关于javascript - 如何链接 Sequelize model.create() promise 以便它们按顺序执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61700176/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com