繁体   English   中英

链接承诺链

[英]Linking promise chains

我有一个工作承诺链:

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三件事:

  1. 它并行而不是顺序地开始所有操作
  2. 它展示了承诺创建反模式 没有startSyncstartSync创建新的startSync 已经有一个可以与之合作的承诺
  3. 它确保其分辨率值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
}

如果您使syncCatssyncTreessyncCars使用db syncCars解决它们的承诺,就像这样:

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 resolution值,建议从上面删除该部分。 :-)

感谢TJ和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;
}

现在,正如TJ指出的那样,每个.then的调用方式都不正确。 他在回答中解释得更好。 我被一些误解的数据库层排队救了。 syncTrees()syncCars() 应该并行运行。

如果我对它的理解正确,那么您将拥有一个数据库数组,并且想要一个一个地同步它们,即对dbs [0]进行同步,对dbs [1]的完全同步,依此类推。 如果是正确的话,你可以做这样的事情。

var syncMultipleDBs = (dataBases) {
    var db = dataBases.shift();
    if (!db) {
        return;
    }
    startSync(db).then(syncMultipleDBs.bind(null, dataBases));
};

syncsyncMultipleDBs(dbs.slice());

我希望这将有所帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM