Tablica zwarć. Dla Jak przerwanie połączenia


1569
[1,2,3].forEach(function(el) {
    if(el === 1) break;
});

Jak mogę to zrobić za pomocą nowej forEachmetody w JavaScript? Próbowałem return;, return false;i break.breakulega awarii i returnnie wykonuje nic poza kontynuowaniem iteracji.


6
Warto zauważyć, że chociaż returnrzeczywiście kontynuuje iterację, pominie każdy kod, który pojawi się po nim w bloku. Weźmy na przykład ten kod [1,2,3].forEach(function(el) { if(el === 2) { console.log(`Match on 2!`); return; } console.log(el); });:. console.log(el);Zostaną one pominięte, gdy 2 zostaną dopasowane.
Shane

5
TL; DR: Większość z was zaoszczędzę dużo czasu. Ostatnio używałem dużo JS. Odpowiedź (spośród 28 ...), której prawdopodobnie szukasz, brzmi następująco: stackoverflow.com/a/32101207/1599699
Andrew

Odpowiedzi:


2141

Nie ma wbudowanego zdolności breakw forEach. Aby przerwać wykonywanie, musisz rzucić jakiś wyjątek. na przykład.

var BreakException = {};

try {
  [1, 2, 3].forEach(function(el) {
    console.log(el);
    if (el === 2) throw BreakException;
  });
} catch (e) {
  if (e !== BreakException) throw e;
}

Wyjątki JavaScript nie są strasznie ładne. Tradycyjna forpętla może być bardziej odpowiednia, jeśli naprawdę potrzebujesz breakw niej wejść .

Posługiwać się Array#some

Zamiast tego użyj Array#some:

[1, 2, 3].some(function(el) {
  console.log(el);
  return el === 2;
});

Działa to, ponieważ somezwraca truejak najszybciej jakikolwiek callback, wykonywany w kolejności tablicowej, return true, zwiera wykonanie reszty.

some, jego odwrotność every(która zatrzyma się na a return false) i forEachwszystkie metody ECMAScript Piątej Edycji, które trzeba będzie dodać do Array.prototypeprzeglądarek, w których ich brakuje.


109
Nie jest to ani bardziej czytelne, ani wydajniejsze niż zwykłe użycie pętli for. Odpowiedź powinna brzmieć: „nie używaj dla każdego w tym przypadku” -1
BT

37
Myślę, że „trochę” jest w porządku, dlaczego nie skorzystać z wczesnej optymalizacji
wyjścia-

28
Dziękuję za uwagę, somea odpowiedź everypowinna znajdować się na GÓRZE. Nie mogę zrozumieć, dlaczego ludzie uważają, że jest mniej czytelny. To jest po prostu niesamowite!
Karl Adler

9
Zastosowanie Array#somejest naprawdę miłe. Po pierwsze, jest kompatybilny z większością przeglądarek, w tym ie9 i Firefox 1.5. Moim przykładowym przypadkiem użycia będzie znalezienie indeksu w tablicy zakresów [a, b], gdzie liczba znajduje się między dolną granicą a górną parą granic, przetestuj i zwróć true, gdy zostanie znaleziona. for..ofbyłoby kolejnym najlepszym rozwiązaniem tylko dla nowszych przeglądarek.
Sojimaxi

95
Obsługa wyjątków NIGDY nie powinna być stosowana jako przepływ kontrolny. KROPKA.
szczery

479

Istnieje teraz jeszcze lepszy sposób na wykonanie tego w ECMAScript2015 (alias ES6) przy użyciu nowej pętli for . Na przykład ten kod nie drukuje elementów tablicy po liczbie 5:

let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
for (let el of arr) {
  console.log(el);
  if (el === 5) {
    break;
  }
}

Z dokumentów:

Zarówno dla ... w, jak i ... wypowiedzi iteruje coś. Główna różnica między nimi polega na tym, co powtarzają. Instrukcja for ... iteruje iterowalne policzalne właściwości obiektu w oryginalnej kolejności wstawiania. Instrukcja for ... iteruje dane, dla których obiekt iteracyjny określa iterację.

Potrzebujesz indeksu w iteracji? Możesz użyć Array.entries():

for (const [index, el] of arr.entries()) {
  if ( index === 5 ) break;
}

4
@ superuphero Możesz uzyskać indeks elementu w pętli for ... po prostu musisz użyć entries. for (const [index, element] of someArray.entries ()) {// ...}
blackxored

czy nie zaleca się, aby nie używać ... z tablicami?
schehata

4
@emostafa Jesteś rację dla w pętli nie jest zalecany dla tablic, ale to podejście rzeczywiście wykorzystuje do z pętli.
canac

To jest „za” i jest to naprawdę czyste rozwiązanie ... ale jest to również funkcja ES6, więc pamiętaj, że będzie to działać tylko wtedy, gdy twoje środowisko jest skonfigurowane dla ES6.
Czad

Często używam tego rozwiązania i używam go również do obiektów. W przypadku obiektów możesz to zrobić, Object.entries(myObject)a następnie użyć dokładnie tak, jak w for..inprzypadku tablicy. Zauważ, że tablice JS są w zasadzie obiektami pod maską: blog.niftysnippets.org/2011/01/myth-of-arrays.html
Andrew

204

Możesz użyć każdej metody:

[1,2,3].every(function(el) {
    return !(el === 1);
});

ES6

[1,2,3].every( el => el !== 1 )

do obsługi starej przeglądarki użyj:

if (!Array.prototype.every)
{
  Array.prototype.every = function(fun /*, thisp*/)
  {
    var len = this.length;
    if (typeof fun != "function")
      throw new TypeError();

    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this &&
          !fun.call(thisp, this[i], i, this))
        return false;
    }

    return true;
  };
}

więcej szczegółów tutaj .


10
Ładne i czyste w ES6 teraz -[1,2,3].every( el => el !== 1 )
metame

1
@Valdemar, ale czy every gwarantuje, że połączenia będą wykonywane po kolei?
Pacerier

4
@Pacerier, możesz zobaczyć algorytm w specyfikacji ES6, że indeks kzaczyna się od 0 i jest zwiększany o 1: http://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.every
XP1

@ XP1: Czy wszyscy implementatorzy muszą to zrobić w ten sposób?
Pacerier,

1
@Pacerier, tak, najpopularniejsze implementacje działają poprawnie. Jeśli martwisz się implementacjami osadzonymi, zwykle jest to Opera lub webkit. Metoda co wywołuje callbackfn jeden raz dla każdego elementu w tablicy, w porządku rosnącym , aż znajdzie taki, w którym callbackfn zwraca false. Spójrz także na krok 7. Niech k będzie wynosić 0. i 8.e Zwiększ k o 1.
Valdemar_Rudolfovich

78

Cytowanie z dokumentacji MDNArray.prototype.forEach() :

Nie jest w żaden sposób do zatrzymania lub uszkodzenia w forEach()pętli innych niż wyrzucanie wyjątek. Jeśli potrzebujesz takiego zachowania, .forEach()metoda jest niewłaściwym narzędziem , zamiast tego użyj zwykłej pętli. Jeśli testujesz elementy tablicy dla predykatu i potrzebujesz logicznej wartości zwracanej, możesz użyć every()lub some()zamiast tego.

W swoim kodzie (w pytaniu), zgodnie z sugestią @bobince, użyj Array.prototype.some()zamiast tego. Bardzo dobrze pasuje do twojej skrzynki użytkownika.

Array.prototype.some()wykonuje funkcję wywołania zwrotnego raz dla każdego elementu obecnego w tablicy, dopóki nie znajdzie takiego, w którym wywołanie zwrotne zwraca prawdziwą wartość (wartość, która staje się prawdziwa po przekształceniu w a Boolean). Jeśli taki element zostanie znaleziony, some()natychmiast zwraca wartość true. W przeciwnym razie some()zwraca false. wywołanie zwrotne jest wywoływane tylko dla indeksów tablicy, którym przypisano wartości; nie jest wywoływany dla indeksów, które zostały usunięte lub którym nigdy nie przypisano wartości.


1
To jest poprawna odpowiedź. „niektóre” robią dokładnie to, co zrobiłby foreach / break. Pętla, aż iteracja n = prawda.
Antony Booth,

74

Niestety w tym przypadku będzie znacznie lepiej, jeśli nie użyjesz forEach. Zamiast tego użyj zwykłej forpętli, a teraz będzie działać dokładnie tak, jak można się spodziewać.

var array = [1, 2, 3];
for (var i = 0; i < array.length; i++) {
  if (array[i] === 1){
    break;
  }
}

27
Szokuje mnie, że najwyższy głos jest najgorszą możliwą implementacją, w porównaniu do wyższej wydajności, mniejszego kodu i lepszej czytelności tej poprawnej odpowiedzi. Rzuć wyjątek ... naprawdę? Czy tradycyjna pętla for po prostu nie wystarcza?
gdbj,

2
@gdbj Zgadzam się z twoim stwierdzeniem i zastosowałem tę metodę, ale to, co naprawdę mnie szokuje, to to, że nie ma sposobu na wyjście z forEach bez tych hacków, teraz to zły projekt.
ScottN,

28

Rozważ użycie jquery„s eachmetody, ponieważ pozwala na return false wewnątrz funkcji oddzwaniania:

$.each(function(e, i) { 
   if (i % 2) return false;
   console.log(e)
})

Biblioteki Lodash zapewniają również takeWhilemetodę, która może być powiązana z mapą / zmniejszeniem / foldem itp .:

var users = [
  { 'user': 'barney',  'active': false },
  { 'user': 'fred',    'active': false },
  { 'user': 'pebbles', 'active': true }
];

_.takeWhile(users, function(o) { return !o.active; });
// => objects for ['barney', 'fred']

// The `_.matches` iteratee shorthand.
_.takeWhile(users, { 'user': 'barney', 'active': false });
// => objects for ['barney']

// The `_.matchesProperty` iteratee shorthand.
_.takeWhile(users, ['active', false]);
// => objects for ['barney', 'fred']

// The `_.property` iteratee shorthand.
_.takeWhile(users, 'active');
// => []

1
Dobry powód, aby użyć jQuery. forEach w natywnym javascript wciąż brakuje.
Alex Grande,

3
@AlexGrande forEach jQuery i forEach JavaScript nie są kompatybilne.
Bjorn,

10
JavaScript jest używany w wielu miejscach, w których jQuery nie jest opcją.
JBRWilkinson


18

Jeśli chcesz skorzystać z sugestii Deana Edwarda i rzucić błąd StopIteration, aby wyjść z pętli bez wychwytywania błędu, możesz użyć następującej funkcji ( oryginalnie stąd ):

// Use a closure to prevent the global namespace from be polluted.
(function() {
  // Define StopIteration as part of the global scope if it
  // isn't already defined.
  if(typeof StopIteration == "undefined") {
    StopIteration = new Error("StopIteration");
  }

  // The original version of Array.prototype.forEach.
  var oldForEach = Array.prototype.forEach;

  // If forEach actually exists, define forEach so you can
  // break out of it by throwing StopIteration.  Allow
  // other errors will be thrown as normal.
  if(oldForEach) {
    Array.prototype.forEach = function() {
      try {
        oldForEach.apply(this, [].slice.call(arguments, 0));
      }
      catch(e) {
        if(e !== StopIteration) {
          throw e;
        }
      }
    };
  }
})();

Powyższy kod daje możliwość uruchomienia kodu takiego jak poniżej bez konieczności wykonywania własnych klauzul try-catch:

// Show the contents until you get to "2".
[0,1,2,3,4].forEach(function(val) {
  if(val == 2)
    throw StopIteration;
  alert(val);
});

Należy pamiętać, że spowoduje to aktualizację funkcji Array.prototype.forEach, jeśli już istnieje. Jeśli jeszcze nie istnieje, nie będzie go modyfikować.


11

Krótka odpowiedź: użyj for...breakdo tego lub zmień kod, aby uniknąć złamania forEach. Nie używaj .some()ani .every()do emulacji for...break. Przepisz kod, aby uniknąć for...breakpętli lub użyj for...break. Za każdym razem, gdy używasz tych metod jako for...breakalternatywnego, Bóg zabija kociaka.

Długa odpowiedź:

.some()i .every()obie zwracają booleanwartość, .some()zwraca, truejeśli istnieje jakikolwiek element, dla którego przekazana funkcja zwraca true, każde zwracafalse jeśli istnieje jakikolwiek element, dla którego przekazana funkcja zwracafalse . To właśnie oznaczają te funkcje. Używanie funkcji do tego, co nie oznaczają, jest znacznie gorsze niż używanie tabel do układu zamiast CSS, ponieważ frustruje każdego, kto czyta twój kod.

Ponadto jedynym możliwym sposobem wykorzystania tych metod jako for...breakalternatywy jest .some()wywołanie efektów ubocznych (zmiana niektórych zmiennych poza funkcją wywołania zwrotnego), i to niewiele różni się odfor...break .

Zatem użycie .some()lub .every()jako for...breakalternatywa pętli nie jest wolna od skutków ubocznych, nie jest to wtedy dużo czystszefor...break , jest to frustrujące, więc nie jest lepiej.

Zawsze możesz przepisać kod, aby nie było potrzeby for...break. Możesz filtrować tablicę za pomocą .filter(), możesz podzielić tablicę za pomocą .slice()i tak dalej, następnie użyj .forEach()lub .map()dla tej części tablicy.


użycie .filter jest właściwie właściwym rozwiązaniem dla wielu przypadków użycia do złamania.
TKoL

Co z wydajnością? Czy filtr często nie wpływa na wydajność?
tfrascaroli

Tak, prototyp tablicy filtrów może być ciężki. Uwielbiam to, ale może to mieć wpływ na wydajność, jeśli jest nadużywane.
Czad

@tfrascaroli użyj for...breakpętli, jeśli potrzebujesz wydajności. forPętla jest najbardziej wydajnych niż narzędzie iteracja .forEach(), .any(), .map(), .filter()itd.
Max

6

To jest coś, co wymyśliłem, aby rozwiązać problem ... Jestem prawie pewien, że rozwiązuje problem, który miał pierwotny pytający:

Array.prototype.each = function(callback){
    if(!callback) return false;
    for(var i=0; i<this.length; i++){
        if(callback(this[i], i) == false) break;
    }
};

A potem nazwałbyś to używając:

var myarray = [1,2,3];
myarray.each(function(item, index){
    // do something with the item
    // if(item != somecondition) return false; 
});

Zwrócenie wartości false w funkcji wywołania zwrotnego spowoduje przerwanie. Daj mi znać, jeśli to nie zadziała.


1
=== falsemoże być lepsza niż == false, abyś nie musiał jawnie zwracać wartości true (lub truey), aby kontynuować pętlę, aby ścieżka sterowania nie zwróciła wartości i pętla nieoczekiwanie pękła.
Jake

6

Kolejna koncepcja, którą wymyśliłem:

function forEach(array, cb) {
  var shouldBreak;
  function _break() { shouldBreak = true; }
  for (var i = 0, bound = array.length; i < bound; ++i) {
    if (shouldBreak) { break; }
    cb(array[i], i, array, _break);
  }
}

// Usage

forEach(['a','b','c','d','e','f'], function (char, i, array, _break) {
  console.log(i, char);
  if (i === 2) { _break(); }
});


Składnia jest podobna do [NSArray enumerateObjectsUsingBlock], dzięki!
Chrstph SLN

@Drenai podpis jest analogiczny do rodzimego Array.prototype.forEach(). fori breakistniał na długo przed tym pytaniem; PO szukał tego zachowania przy użyciu, bardziej funkcjonalny forEach.
c24w

@Drenai usunął teraz swój komentarz (ale pozostawił opinię), w której wspomniano, że podpis tego rozwiązania jest trudny do zapamiętania i niepotrzebny, gdy można rozwiązać problem za pomocą for...ini break.
c24w

5

Znalazłem to rozwiązanie w innej witrynie. Możesz owinąć forEach w scenariuszu try / catch.

if(typeof StopIteration == "undefined") {
 StopIteration = new Error("StopIteration");
}

try {
  [1,2,3].forEach(function(el){
    alert(el);
    if(el === 1) throw StopIteration;
  });
} catch(error) { if(error != StopIteration) throw error; }

Więcej informacji tutaj: http://dean.edwards.name/weblog/2006/07/enum/


2
Nie używaj wyjątków jako instrukcji przepływu kontroli. Użyj go do obsługi nieoczekiwanych wyników.
Max

5
var array = [1,2,3,4];

for(var item of array){
    console.log(item);
    if(item == 2){
       break;
    }
}

4

Jeśli nie potrzebujesz dostępu do tablicy po iteracji, możesz wyskoczyć, ustawiając długość tablicy na 0. Jeśli nadal potrzebujesz jej po iteracji, możesz ją sklonować za pomocą plasterka.

[1,3,4,5,6,7,8,244,3,5,2].forEach(function (item, index, arr) {
  if (index === 3) arr.length = 0;
});

Lub z klonem:

var x = [1,3,4,5,6,7,8,244,3,5,2];

x.slice().forEach(function (item, index, arr) {
  if (index === 3) arr.length = 0;
});

Co jest znacznie lepszym rozwiązaniem niż zgłaszanie przypadkowych błędów w kodzie.


dobrze zrobione :) ale jeśli istnieją pewne działania po przypisaniu array.lengthdo 0nich są stosowane w bieżącej iteracji, więc prawdopodobnie jest to czasami lepiej jest użyć returnpo takim przypisanie
zhibirc

4

To jest pętla for, ale zachowuje odwołanie do obiektu w pętli, podobnie jak forEach (), ale możesz się wyrwać.

var arr = [1,2,3];
for (var i = 0, el; el = arr[i]; i++) {
    if(el === 1) break;
}

4

Jak wspomniano wcześniej, nie możesz się złamać .forEach().

Oto nieco bardziej nowoczesny sposób wykonywania foreach za pomocą Iteratorów ES6. Umożliwia bezpośredni dostęp do index/ valuepodczas iteracji.

const array = ['one', 'two', 'three'];

for (const [index, val] of array.entries()) {
  console.log('item:', { index, val });
  if (index === 1) {
    console.log('break!');
    break;
  }
}

Wynik:

item: { index: 0, val: 'one' }
item: { index: 1, val: 'two' }
break!

Spinki do mankietów


3

Jeszcze inne podejście

        var wageType = types.filter(function(element){
            if(e.params.data.text == element.name){ 
                return element;
            }
        });
        console.dir(wageType);

2

W tym celu używam nullhack , próbuje uzyskać dostęp do właściwości null, która jest błędem:

try {
  [1,2,3,4,5]
  .forEach(
    function ( val, idx, arr ) {
      if ( val == 3 ) null.NULLBREAK;
    }
  );
} catch (e) {
  // e <=> TypeError: null has no properties
}
//

1
Dlaczego nie tylko throw BREAK?
Bergi,

1

Jeśli chcesz zachować forEach składnię, jest to sposób na utrzymanie jej wydajności (chociaż nie jest tak dobry jak zwykła pętla for). Natychmiast sprawdź zmienną, która wie, czy chcesz wyjść z pętli.

W tym przykładzie użyto funkcji anonimowej do utworzenia zakresu funkcji, wokół forEachktórego należy przechowywać wykonane informacje.

(function(){
    var element = document.getElementById('printed-result');
    var done = false;
    [1,2,3,4].forEach(function(item){
        if(done){ return; }
        var text = document.createTextNode(item);
        element.appendChild(text);
        if (item === 2){
          done = true;
          return;
        }
    });
})();
<div id="printed-result"></div>

Moje dwa centy.


1

Wiem, że to nie w odpowiedni sposób. To nie jest przerwa w pętli. To jest Jugad

let result = true;
[1, 2, 3].forEach(function(el) {
    if(result){
      console.log(el);
      if (el === 2){
        result = false;
      }
    }
});



0

Zgadzam się z @bobince, przegłosowałem.

Również FYI:

Prototype.js ma coś w tym celu:

<script type="text/javascript">
  $$('a').each(function(el, idx) {
    if ( /* break condition */ ) throw $break;
    // do something
  });
</script>

$break zostanie przechwycony i obsłużony przez Prototype.js wewnętrznie, przerywając „każdy” cykl, ale nie generując błędów zewnętrznych.

Aby uzyskać szczegółowe informacje, zobacz Prototype.JS API .

jQuery ma również sposób, po prostu zwróć false w module obsługi, aby wcześniej przerwać pętlę:

<script type="text/javascript">
  jQuery('a').each( function(idx) {
    if ( /* break condition */ ) return false;
    // do something

  });
</script>

Szczegółowe informacje można znaleźć w interfejsie API jQuery .


0

Nie jest to najbardziej wydajne, ponieważ nadal cyklicznie wszystkie elementy, ale pomyślałem, że warto rozważyć bardzo proste:

let keepGoing = true;
things.forEach( (thing) => {
  if (noMore) keepGoing = false;
  if (keepGoing) {
     // do things with thing
  }
});

continueto słowo kluczowe, kod jest błędem składni.
Bergi,

3
Biorąc pod uwagę, że i tak używasz ES6, powinieneś po prostu przełączyć się na for ofpętlę i break;od tego, jak zwykle.
Bergi,

stałe, a prawda - ale głównie za pomocą ES6 dla zwięzłości
martyman

0

możesz postępować zgodnie z poniższym kodem, który działa dla mnie:

 var     loopStop = false;
YOUR_ARRAY.forEach(function loop(){
    if(loopStop){ return; }
    if(condition){ loopStop = true; }
});

Dlaczego -1? nie jest brzydsze niż złapanie wyjątku, czyli większy hack IMHO.
Byron Whitlock

0

Wolę używać for in

var words = ['a', 'b', 'c'];
var text = '';
for (x in words) {
    if (words[x] == 'b') continue;
    text += words[x];
}
console.log(text);

for indziała podobnie forEach, i możesz dodać funkcję powrotu do wyjścia w środku. Również lepsza wydajność.


0

Jeśli potrzebujesz przerwać na podstawie wartości elementów, które są już w twojej tablicy, tak jak w twoim przypadku (tj. Jeśli warunek przerwania nie zależy od zmiennej czasu wykonywania, która może się zmienić po przypisaniu tablicy wartości jej elementów), możesz również użyć kombinacji funkcji slice () i indexOf () w następujący sposób.

Jeśli musisz przerwać, gdy forEach osiągnie „Apple”, możesz użyć

var fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
var fruitsToLoop = fruits.slice(0, fruits.indexOf("Apple"));
// fruitsToLoop = Banana,Orange,Lemon

fruitsToLoop.forEach(function(el) {
    // no need to break
});

Jak stwierdzono w W3Schools.com metoda slice () zwraca wybrane elementy w tablicy, jako nowy obiekt tablicy. Oryginalna tablica nie zostanie zmieniona.

Zobacz to w JSFiddle

Mam nadzieję, że to komuś pomoże.


0

Można utworzyć wariant forEach, który pozwala na break, continue, return, a nawet async/ await: (przykład napisany na maszynie)

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];
    }
};

Stosowanie:

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);
}

-1

spróbuj z „znajdź”:

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" }

-1

Tak, można kontynuować i wyjść z pętli forEach.

Aby kontynuować, możesz użyć return, pętla będzie kontynuowana, ale bieżąca funkcja się zakończy.

Aby wyjść z pętli, możesz ustawić trzeci parametr na 0, ustawić pustą tablicę. Pętla nie będzie kontynuowana, obecna funkcja tak, więc możesz użyć „return”, aby zakończyć, jak wyjście w normalnej pętli for ...

To:

[1,2,3,4,5,6,7,8,9,10].forEach((a,b,c) => {
    console.log(a);
    if(b == 2){return;}
    if(b == 4){c.length = 0;return;}
    console.log("next...",b);
});

wydrukuje to:

1
next... 0
2
next... 1
3
4
next... 3
5

-2

Wcześniej mój kod był poniżej

 this.state.itemsDataSource.forEach((item: any) => {
                if (!item.isByPass && (item.invoiceDate == null || item.invoiceNumber == 0)) {

                    return false;
                }
            });

Zmieniłem poniżej, zostało to naprawione.

 for (var i = 0; i < this.state.itemsDataSource.length; i++) {
                var item = this.state.itemsDataSource[i];
                if (!item.isByPass && (item.invoiceDate == null || item.invoiceNumber == 0)) {

                    return false;
                }
            }
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.