我有一个有效的 promise 链:
function startSync(db) {
var promise = new Promise(function(resolve, reject) {
syncCats(db)
.then(syncTrees(db))
.then(syncCars(db))
...
.then(resolve());
});
return promise;
}
这很好用。它执行这些函数调用中的每一个,等待每个调用完成,然后再触发另一个。这些函数中的每一个都返回一个 promise ,如下所示:
function syncCaesar(db) {
var promise = new Promise(resolve, reject) {
// do aysnc db calls, and whatnot, resolving/rejecting appropriately
}
return promise;
}
我需要在一系列数据库上按顺序运行这条链。
我在这里尝试过其他解决方案,但它们会同时触发 syncCats()
。
例如:
var promise = Promise.resolve();
dbs.forEach(function(db) {
promise = promise.then(startSync(db));
}
同时触发 syncCats(db[0])
和 syncCats(db[1])
。
编辑:
执行 startSync(dbs[0]).then(startSync(dbs[1]));
行为相同。
Edit2:也执行相同的操作:
dbs.forEach(function(db) {
promise = promise.then(function() {
return startSync(db);
}
}
最佳答案
您正在调用 startSync
,然后将其返回值传递给then
。所以很自然地,如果你这样做两次,它会并行启动该过程两次。
相反,传入一个在调用 startSync
之前不调用它的函数:
var promise = Promise.resolve();
dbs.forEach(function(db) {
promise = promise.then(function() { startSync(db); });
});
或使用 ES2015:
let promise = Promise.resolve();
dbs.forEach(function(db) {
promise = promise.then(_ => startSync(db));
});
另外,关于 startSync
的三件事:
- 它并行而不是顺序地开始所有操作
- 它展示了 promise 创建反模式。
startSync
没有理由创建一个新的 promise ;它已经可以使用的 promise - 它确保其解析值是
undefined
如果你真的想要像那样并行运行的操作,我建议更明确一点:
function startSync(db) {
return Promise.all([
syncCats(db),
syncTrees(db),
syncCars(db)
])
.then(_ => undefined); // This does #3
}
...但是您也可以避免反模式:
// Still run in parallel!
function startSync(db) {
return syncCats(db)
.then(syncTrees(db))
.then(syncCars(db))
.then(_ => undefined); // Does #3
}
如果您想让它们按顺序排列,则需要传递函数,而不是调用它们的结果:
function startSync(db) {
return syncCats(db)
.then(_ => syncTrees(db))
.then(_ => syncCars(db))
.then(_ => undefined); // Again, does #3
}
如果您让 syncCats
、syncTrees
和 syncCars
使用 db
解决它们的 promise ,如下所示:
function syncCats(db) {
return startSomethingAsync().then(_ => db);
}
...那么它可能是:
function startSync(db) {
return syncCats(db)
.then(syncTrees)
.then(syncCars)
.then(_ => undefined); // Only here for #3
}
...因为每个都将接收 db
作为其第一个参数。
最后,如果您不需要强制将 undefined
作为 promise 解析值,我建议从上面删除该部分。 :-)
关于javascript - 链接 promise 链,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43535392/