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()
,它只会在您第一次调用它时对承诺做任何事情。显然,您正在解决循环中第一个匹配的承诺,然后继续运行循环的其余部分。因此,当循环完成时,承诺没有连接到。我无法判断是否不需要循环继续。如果你这样做,那么承诺是不正确的连接