Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
javascript中循环内外的条件链接承诺_Javascript_Loops_Promise_Control Flow - Fatal编程技术网

javascript中循环内外的条件链接承诺

javascript中循环内外的条件链接承诺,javascript,loops,promise,control-flow,Javascript,Loops,Promise,Control Flow,在下面的代码中,当循环中的条件满足时,我们无法确定调用异步函数的顺序 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') { asyncFuncti

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

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));
我相信这个问题以前已经解决过,但我找不到合适的搜索键盘


谢谢

如果只有一个兄弟姐妹可以满足标准,使用
查找将简化您的代码:

const selected=[…同级].find(elem=>elem.getAttribute('data-selected')=='true');
checksides
标记为
async
,使其始终返回承诺,并在适当的时候返回
async函数
承诺:

是否返回所选?asyncFunction(选中):空;
然后您可以像以前一样将其链接:

检查同级(同级)。然后(()=>异步函数(元素));
总的来说,你会得到这样的东西:

异步函数检查同级(同级){
const selected=[…同级].find(elem=>elem.getAttribute('data-selected')=='true');
返回所选?异步函数(所选):空
}
检查同级(同级)。然后(()=>asyncFunction(元素));

如果只有一个同级可以满足标准,使用
查找将简化您的代码:

const selected=[…同级].find(elem=>elem.getAttribute('data-selected')=='true');
checksides
标记为
async
,使其始终返回承诺,并在适当的时候返回
async函数
承诺:

是否返回所选?asyncFunction(选中):空;
然后您可以像以前一样将其链接:

检查同级(同级)。然后(()=>异步函数(元素));
总的来说,你会得到这样的东西:

异步函数检查同级(同级){
const selected=[…同级].find(elem=>elem.getAttribute('data-selected')=='true');
返回所选?异步函数(所选):空
}
检查同级(同级)。然后(()=>asyncFunction(元素));

有几种方法。其中之一是使用
数组。将
减少为:

[…同级].减少(
异步(上一个,同级))=>{
//等待最初/以前的承诺(放弃结果)
等待上证;
//此条件只能满足一次
//(只有一个同级可以将数据选择为true)
if(sibling.getAttribute('data-selected')=='true'){
//返回异步函数承诺
返回异步函数(同级);
}
//异步函数总是返回一个承诺。
//不需要归还任何东西
//初始承诺自动解除
},Promise.resolve())
//一旦全部执行完毕
.然后(()=>异步函数(元素));

有几种方法。其中之一是使用
数组。将
减少为:

[…同级].减少(
异步(上一个,同级))=>{
//等待最初/以前的承诺(放弃结果)
等待上证;
//此条件只能满足一次
//(只有一个同级可以将数据选择为true)
if(sibling.getAttribute('data-selected')=='true'){
//返回异步函数承诺
返回异步函数(同级);
}
//异步函数总是返回一个承诺。
//不需要归还任何东西
//初始承诺自动解除
},Promise.resolve())
//一旦全部执行完毕
.然后(()=>异步函数(元素));

谢谢。如果我错了,请纠正我,我相信find()不能用于节点列表(兄弟姐妹是html元素的节点列表,我没有指定这一点),或者可以吗?使用
Array.from(兄弟姐妹)。find(…)
或使用扩展运算符
[…兄弟姐妹)。find(…)
哦。正确的。很抱歉我将用@emi正确建议的排列更新答案。可能是find在这种情况下不起作用吗?我制作了一个jsFiddle来测试它:您正在调用
document.querySelector('li')
,它将返回其中一个。如果只得到一个元素,则无需将其转换为数组或调用find。也许你是想打电话给我?谢谢。如果我错了,请纠正我,我相信find()不能用于节点列表(兄弟姐妹是html元素的节点列表,我没有指定这一点),或者可以吗?使用
Array.from(兄弟姐妹)。find(…)
或使用扩展运算符
[…兄弟姐妹)。find(…)
哦。正确的。很抱歉我将用@emi正确建议的排列更新答案。可能是find在这种情况下不起作用吗?我制作了一个jsFiddle来测试它:您正在调用
document.querySelector('li')
,它将返回其中一个。如果只得到一个元素,则无需将其转换为数组或调用find。也许你想改为调用?循环与异步调用没有任何关系,所以在涉及承诺之前先完成循环。另外,
.forEach()
现在应该避免使用,因为它的循环控制远远少于普通的
for
循环,特别是当你找到你要找的东西后想要中止循环时。抱歉@jfriend00,但我不完全理解你所说的“在涉及承诺之前完成循环”的意思你能举个例子吗?谢谢。您在循环中调用
resolve()
,它只会在您第一次调用它时对承诺做任何事情。显然,您正在解决循环中第一个匹配的承诺,然后继续运行循环的其余部分。因此,当循环完成时,承诺没有连接到。我无法判断是否不需要循环继续。如果你这样做,那么承诺是不正确的连接