javascript - 链接 promise 链

标签 javascript promise

我有一个有效的 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 的三件事:

  1. 它并行而不是顺序地开始所有操作
  2. 它展示了 promise 创建反模式startSync 没有理由创建一个新的 promise ;它已经可以使用的 promise
  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 解决它们的 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/

相关文章:

javascript - 扩展原型(prototype)函数而不覆盖它

javascript - JS - Knex,将函数传递给 Transaction

node.js - 拒绝(TypeError): Cannot read property 'setState' of undefined,未捕获( promise )TypeError:无法读取未定义的属性 'setState'

javascript - 如果使用 await,setTimeout 的同步使用会停止代码吗?

javascript - promise Q 无法始终如一地工作

javascript - Promise.all 的奇怪行为

javascript - 我只想从数组中提取某些值

javascript - Ace 编辑器 + jQueryUI 选项卡杀死了我的浏览器

javascript - 虽然可见,但如何使此对话框阻止访问其余页面内容?

javascript - 将复杂的输入名称转换为数组