如何使用promise强制执行特定的执行顺序
How to enforce a specific execution order using promises?
这是程序代码:
jobQueueManager.addSource = (source) => {
console.log('addSource', 'source', source);
return new P(
(resolve) => {
connection.beginTransaction((errorTransaction) => {
if (errorTransaction) {
throw new Error('Error starting a transaction.');
}
connection.query('SELECT `id` FROM `source` WHERE `country_code` = ? AND `nid` = ?', [
source.countryCode,
source.nid
], (errorSelect, rows) => {
if (errorSelect) {
console.log('errorSelect', errorSelect);
throw new Error('Error selecting a source.');
}
// This should be able to find the row after the second time .addSource has been called
// with the same data. But because second "select" happens before the first query is
// commited, it does not.
console.log('select source', 'rows', rows);
if (rows.length === 0) {
connection.query('INSERT INTO `source` SET ?', {
country_code: source.countryCode,
nid: source.nid
}, (errorInsert, result) => {
if (errorInsert) {
throw new Error('Error inserting a source.');
}
console.log('insert source', 'source', source);
resolve(result.insertId);
});
} else {
resolve(rows[0].id);
}
});
});
})
.then((sourceId) => {
return new P((resolve) => {
connection.commit((errorCommit) => {
console.log('commit source');
if (errorCommit) {
throw new Error('Error committing a transaction.');
}
resolve({
id: sourceId,
...source
});
});
});
})
.tap((sourceEntity) => {
console.log('sourceEntity', sourceEntity);
});
};
以下是执行程序的指令:
Promise
.all([
jobQueueManager
.addSource({
countryCode: 'uk',
nid: 'foo'
}),
jobQueueManager
.addSource({
countryCode: 'uk',
nid: 'foo'
})
,
jobQueueManager
.addSource({
countryCode: 'uk',
nid: 'foo'
})
]);
这是输出:
addSource source { countryCode: 'uk', nid: 'foo' }
addSource source { countryCode: 'uk', nid: 'foo' }
addSource source { countryCode: 'uk', nid: 'foo' }
select source rows []
select source rows []
select source rows []
insert source source { countryCode: 'uk', nid: 'foo' }
insert source source { countryCode: 'uk', nid: 'foo' }
insert source source { countryCode: 'uk', nid: 'foo' }
commit source
sourceEntity { id: 1, countryCode: 'uk', nid: 'foo' }
commit source
sourceEntity { id: 2, countryCode: 'uk', nid: 'foo' }
commit source
sourceEntity { id: 3, countryCode: 'uk', nid: 'foo' }
我希望执行顺序是:
- 选择,插入
- 选择
- 选择
但我得到了:
- 选择
- 选择
- 选择
- 插入
- 插入
- 插入
我做到这一点的唯一方法是使用执行队列,例如
jobQueueManager.addSource = (source) => {
let newSource;
newSource = P.all(jobQueueManager.addSource.executionQueue).then(() => {
return new P(
(resolve) => {
// ...
});
});
jobQueueManager.addSource.executionQueue.push(newSource);
return newSource;
};
jobQueueManager.addSource.executionQueue = [];
这产生了预期的行为:
select source rows []
insert source source { countryCode: 'uk', nid: 'foo' }
commit source
sourceEntity { id: 1, countryCode: 'uk', nid: 'foo' }
select source rows [ RowDataPacket { id: 1 } ]
commit source
sourceEntity { id: 1, countryCode: 'uk', nid: 'foo' }
select source rows [ RowDataPacket { id: 1 } ]
commit source
sourceEntity { id: 1, countryCode: 'uk', nid: 'foo' }
相关文章:
- javascript函数和代码隐藏函数的执行顺序
- Node.js:多个然后'It’执行顺序不正确
- 不同'单击'不同脚本中的回调:我可以控制执行顺序吗
- 代码混淆的执行顺序
- Javascript执行顺序错误
- Javascript执行顺序和回调
- 奇怪的javascript代码执行顺序
- for 循环/递归中的执行顺序
- JavaScript 中的执行顺序问题
- 来自函数 Javascript 的 NaN 返回值 ||函数执行顺序
- 控制承诺执行顺序
- 我可以信任 JavaScript 中声明中的执行顺序吗?
- 使用webcomponenetsjs的HTMLImports以意外的执行顺序加载导入-firefox
- 确保执行顺序:javascript
- Javascript代码的执行顺序
- 保证HTML表单提交和jQuery onclick的执行顺序
- 在ASP.Net中运行javascript时的执行顺序
- jQuery函数执行顺序
- Javascript中绑定到事件的函数的执行顺序
- 淘汰js可观察扩展的执行顺序是什么