首页 > 解决方案 > 在javascript中的循环内部和外部有条件地链接承诺

问题描述

在下面的代码中,当满足循环中的条件时,我们无法确定 asyncFunction 调用的顺序。

siblings.forEach(function(sibling, index) {
  // This condition may only be satisfied once (only one sibling may have data-selected true)
  if (sibling.getAttribute('data-selected') == 'true') { 
        asyncFunction(sibling);     
  }
})

asyncFunction(element);

因为我知道 asyncFunction() 返回一个承诺,所以我可以链接它们以确保顺序:

asyncFunction(sibling).then(asyncFunction(element));

但是如何在考虑条件的情况下做到这一点?

我考虑将循环包装在一个承诺中,该承诺在满足条件或循环结束后解决,但这似乎有点令人费解。

// Untested
function checkSiblings(siblings) {
    let promise = new Promise(function(resolve, reject) {
        siblings.forEach(function(sibling, index) {
          if (sibling.getAttribute('data-selected') == 'true') { 
                resolve(asyncFunction(sibling));    
          }
        })
        resolve();
    })
}

checkSiblings(siblings).then(asyncFunction(element));

我确信这个问题之前已经解决过,但我找不到合适的搜索键盘。

谢谢

标签: javascriptloopspromisecontrol-flow

解决方案


如果只有一个兄弟姐妹可以满足条件,则 usingfind将简化您的代码:

const selected = [...siblings].find( elem => elem.getAttribute('data-selected') == 'true' );

标记checkSiblingsasync它总是返回一个 Promise,并让它asyncFunction在适当的时候返回 Promise:

return selected ? asyncFunction(selected) : null;

然后你可以像以前一样链接它们:

checkSiblings(siblings).then(() => asyncFunction(element));

总之,你会有这样的事情:

async function checkSiblings (siblings) {
  const selected = [...siblings].find( elem => elem.getAttribute('data-selected') == 'true' );
  return selected ? asyncFunction(selected) : null
}

checkSiblings(siblings).then(() => asyncFunction(element));

推荐阅读