我有一个工作承诺链:
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);
}
}
答案 0 :(得分:3)
您正在调用 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
:
startSync
没有理由创造新的承诺;它已经它可以使用的承诺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
解决了承诺,请执行以下操作:
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
作为承诺解析值,我建议从上面删除该部分。 : - )
答案 1 :(得分:0)
感谢T.J和Jaromanda,我能够通过修复startSync()
的解决方法来解决这个问题:
function startSync(db) {
var promise = new Promise(function(resolve, reject) {
syncCats(db)
.then(syncTrees(db)) // not correct way to call, see below
.then(syncCars(db))
...
.then(function() { resolve(); });
});
return promise;
}
现在,正如T.J指出的那样,调用每个.then
的方式都是不正确的。他在答案中解释得更好。我被一些被误解的数据库层排队所挽救。 <{1}}和syncTrees()
应并行运行。
答案 2 :(得分:-1)
如果我理解正确的话,你将拥有一个数据库阵列,并且你想逐个同步它们,即同步dbs [0],一旦完全同步dbs [1],依此类推。如果这是正确的,你可以做这样的事情。
var syncMultipleDBs = (dataBases) {
var db = dataBases.shift();
if (!db) {
return;
}
startSync(db).then(syncMultipleDBs.bind(null, dataBases));
};
syncsyncMultipleDBs(dbs.slice());
我希望这会有所帮助。