我正在实现一些功能,其中从firebase检索一些array类型的数据, 然后从该数组中搜索特定元素,如果存在, 我想中止该函数并返回到调用者。 (本机应用程序)
代码如下:
ref.get().then(snapshot => {
const personArr = snapshot.data().winPerson;
...
if (personArr != undefined) {
personArr.forEach(item => {
if (item == uid.uid) {
alert(`already subscribed`);
return;
}
});
if (prop.first.length != 0) {
uploadHelper(ref, prop, "first");
}
...
}
});
我使用forEach遍历数组,看看是否有匹配的元素。如果匹配,则它应发出警报并返回调用方函数,而无需运行下面的后续代码
if (prop.first.length != 0) {
uploadHelper(ref, prop, "first");
}
但是,假设元素确实存在于数组中, 该代码同时运行警报和uploadHelper函数(通过日志检查)。首先,我认为forEach是异步函数,因此在返回之前先执行uploadHelper; 但是,forEach不是异步函数(经过一些谷歌搜索)。
我不知道为什么如果代码落入if(item == uid.uid)条件并返回,则为什么uploadUpper运行。
感谢您的帮助。谢谢
答案 0 :(得分:2)
它返回到调用者函数:) forEach()
正在与每个元素一起调用函数。因此,您返回的只是该元素的功能。
我想您想在for of
循环。想要进行函数式编程的人想使用.forEach
,但是使用for of
可以达到与.forEach
相同的功能效果(不必编制索引,没有副作用)并且可能更易于使用。 (如果要在每个元素之间等待的地方编写异步代码,则forEach也有问题)
所以,像下面这样重写代码:
for (const item of personArr) {
if (item == uid.uid) {
alert(`already subscribed`);
return;
}
}
答案 1 :(得分:1)
首先,您无法停止forEach。它将始终针对数组的每个元素运行,然后继续执行代码。返回值表明您当前正在迭代的元素将更改为您的返回值。
如果要停止执行,可以使用for-in循环或通用的for循环。
答案 2 :(得分:1)
改为使用此
for (let item of personArr) {
if (item == uid.uid) {
alert(`already subscribed`);
break;
}
}
forEach无法中断,这就是为什么您需要使用for并将其中断的原因。在forEach返回中意味着继续下一个索引而不处理下面的代码不会停止循环
答案 3 :(得分:1)
forEach
处理程序也是一个函数。 (item => ...是箭头函数)因此,从personArr.forEach()
内部返回并不会实际上阻止其余函数的执行。
因此,无论.forEach()做什么,if (prop.first.length != 0)
都将得到检查。
如果目标是仅在未找到uid时运行uploadHelper,则需要稍微更改结构。 像这样:
ref.get().then(snapshot => {
const personArr = snapshot.data().winPerson;
...
if (personArr != undefined) {
const match = personArr.find( item => item === uid.uid );
if ( match ) alert(`already subscribed`);
else if (prop.first.length != 0) {
uploadHelper(ref, prop, "first");
}
// else { /* some other defualt case ? */
...
}
});
如果item实际上与uid.uid的值相同,则您甚至可以使其更简单:
如果personArr.includes( uid.uid )
在uid.uid
内, personArr
应该返回true。