[1,2,3].forEach(function(el) {
if(el === 1) break;
});
如何在JavaScript中使用新的forEach方法实现这一点?我尝试过返回;,return false;和断裂。break崩溃,return只会继续迭代。
[1,2,3].forEach(function(el) {
if(el === 1) break;
});
如何在JavaScript中使用新的forEach方法实现这一点?我尝试过返回;,return false;和断裂。break崩溃,return只会继续迭代。
当前回答
为什么不尝试将函数包装在Promise中?
我提出这个问题的唯一原因是我在API中使用了一个函数,该函数的作用方式与forEach类似。我不希望它在找到值后继续迭代,我需要返回一些东西,所以我只需要解析Promise并以这种方式执行。
traverseTree(doc): Promise<any> {
return new Promise<any>((resolve, reject) => {
this.gridOptions.api.forEachNode((node, index) => {
//the above function is the one I want to short circuit.
if(node.data.id === doc.id) {
return resolve(node);
}
});
});
}
那么你所需要做的就是做一些事情,比如
this.traverseTree(doc).then((result) => {
this.doSomething(result);
});
我上面的例子是在typescript中,只需忽略类型。逻辑应该有助于你“打破”你的循环。
其他回答
没有内置的功能可以为Each进行破解。要中断执行,必须抛出某种异常。
var BreakException={};尝试{[1,2,3]对于每个(函数(el){控制台日志(el);如果(el==2)抛出BreakException;});}捕获(e){如果(e!==BreakException)抛出e;}
JavaScript异常并不漂亮。如果你真的需要打破传统的for循环,那么它可能更合适。
使用数组#some
而是使用Array#some:
[1,2,3]一些(函数(el){控制台日志(el);返回el==2;});
这之所以有效,是因为只要按数组顺序执行的任何回调返回true,就会立即返回true,从而缩短其余回调的执行。
有些,它的逆every(返回false时停止)和forEach都是ECMAScript第五版方法,需要在缺少它们的浏览器上添加到Array.prototype中。
使用数组#间隔
[1,2,3]每(v=>{如果(v>2){return false//“break”}控制台日志(v);return true//如果不中断,则必须返回true});
尝试“查找”:
var myCategories = [
{category: "start", name: "Start", color: "#AC193D"},
{category: "action", name: "Action", color: "#8C0095"},
{category: "exit", name: "Exit", color: "#008A00"}
];
function findCategory(category) {
return myCategories.find(function(element) {
return element.category === category;
});
}
console.log(findCategory("start"));
// output: { category: "start", name: "Start", color: "#AC193D" }
您可以创建forEach的变体,该变体允许break、continue、return甚至async/await:(用TypeScript编写的示例)
export type LoopControlOp = "break" | "continue" | ["return", any];
export type LoopFunc<T> = (value: T, index: number, array: T[])=>LoopControlOp;
Array.prototype.ForEach = function ForEach<T>(this: T[], func: LoopFunc<T>) {
for (let i = 0; i < this.length; i++) {
const controlOp = func(this[i], i, this);
if (controlOp == "break") break;
if (controlOp == "continue") continue;
if (controlOp instanceof Array) return controlOp[1];
}
};
// this variant lets you use async/await in the loop-func, with the loop "awaiting" for each entry
Array.prototype.ForEachAsync = async function ForEachAsync<T>(this: T[], func: LoopFunc<T>) {
for (let i = 0; i < this.length; i++) {
const controlOp = await func(this[i], i, this);
if (controlOp == "break") break;
if (controlOp == "continue") continue;
if (controlOp instanceof Array) return controlOp[1];
}
};
用法:
function GetCoffee() {
const cancelReason = peopleOnStreet.ForEach((person, index)=> {
if (index == 0) return "continue";
if (person.type == "friend") return "break";
if (person.type == "boss") return ["return", "nevermind"];
});
if (cancelReason) console.log("Coffee canceled because: " + cancelReason);
}
同意@bobince,支持。
此外,仅供参考:
Prototype.js有这样的功能:
<script type="text/javascript">
$$('a').each(function(el, idx) {
if ( /* break condition */ ) throw $break;
// do something
});
</script>
$break将由Prototype.js在内部捕获和处理,打破“each”循环,但不会产生外部错误。
有关详细信息,请参见Prototype.JS API。
jQuery也有一种方法,只需在处理程序中返回false,即可尽早中断循环:
<script type="text/javascript">
jQuery('a').each( function(idx) {
if ( /* break condition */ ) return false;
// do something
});
</script>
有关详细信息,请参见jQuery API。
这不是最有效的,因为你仍然循环所有元素,但我认为这可能值得考虑非常简单的:
let keepGoing = true;
things.forEach( (thing) => {
if (noMore) keepGoing = false;
if (keepGoing) {
// do things with thing
}
});