Array korsleting. Untuk Setiap seperti panggilan istirahat

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

Bagaimana saya bisa melakukan ini menggunakan forEachmetode baru dalam JavaScript? Saya sudah mencoba return;, return false;dan break. breakcrash dan returntidak melakukan apa-apa selain melanjutkan iterasi.

Scott Klarenbach
sumber
6
Perlu dicatat bahwa meskipun returnmemang melanjutkan iterasi, itu akan melewatkan kode apa pun yang datang setelah itu di blok. Ambil kode ini misalnya: [1,2,3].forEach(function(el) { if(el === 2) { console.log(`Match on 2!`); return; } console.log(el); });an console.log(el);akan dilewati ketika 2 cocok.
Shane
5
TL; DR: Saya akan menghemat banyak waktu bagi Anda. Saya telah menggunakan banyak JS belakangan ini. Jawaban (dari 28 ...) yang mungkin Anda cari adalah yang ini: stackoverflow.com/a/32101207/1599699
Andrew

Jawaban:

2143

Tidak ada kemampuan bawaan untuk breakmasuk forEach. Untuk menghentikan eksekusi, Anda harus melemparkan pengecualian. misalnya.

var BreakException = {};

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

Pengecualian JavaScript tidak terlalu bagus. forPerulangan tradisional mungkin lebih tepat jika Anda benar-benar perlu breakdi dalamnya.

Menggunakan Array#some

Sebaliknya, gunakan Array#some:

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

Ini berfungsi karena somepengembalian truesegera setelah salah satu dari panggilan balik, dieksekusi dalam urutan array, kembali true, hubungan pendek eksekusi sisanya.

some, kebalikannya every(yang akan berhenti pada a return false), dan forEachsemua metode ECMAScript Fifth Edition yang perlu ditambahkan ke Array.prototypebrowser di mana mereka hilang.

bobince
sumber
111
Ini tidak lebih readible, atau lebih berkinerja daripada hanya menggunakan normal untuk loop. Jawabannya harus "jangan gunakan forEach dalam kasus ini" -1
BT
37
Saya pikir "beberapa" baik-baik saja di sini, mengapa tidak menggunakan optimasi keluar awal-
chrismarx
28
Terima kasih atas perhatiannya somedan every, ini seharusnya ada di TOP dalam jawabannya. Tidak dapat memahami mengapa orang berpikir itu kurang mudah dibaca. Luar biasa!
Karl Adler
9
Penggunaannya Array#somesangat bagus. Pertama ini kompatibel dengan sebagian besar browser termasuk IE9 dan firefox 1.5 juga berfungsi dengan sangat baik. Contoh kasus penggunaan saya adalah menemukan indeks dalam array rentang [a, b] di mana angka berada di antara pasangan batas bawah dan batas atas, uji dan kembalikan benar ketika ditemukan. for..ofakan menjadi solusi terbaik berikutnya meskipun hanya untuk browser yang lebih baru.
Sojimaxi
96
Penanganan pengecualian harus TIDAK PERNAH digunakan sebagai aliran kontrol. TITIK.
jujur
479

Sekarang ada cara yang lebih baik untuk melakukan ini di ECMAScript2015 (alias ES6) menggunakan yang baru untuk loop . Misalnya, kode ini tidak mencetak elemen array setelah angka 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;
  }
}

Dari dokumen:

Baik untuk ... dalam dan untuk ... pernyataan yang berulang atas sesuatu. Perbedaan utama di antara mereka adalah pada apa yang mereka lakukan berulang kali. The for ... dalam pernyataan iterates atas properti enumerable dari suatu objek, dalam urutan penyisipan asli. Untuk ... dari pernyataan iterates atas data bahwa objek iterable mendefinisikan untuk diulangi.

Perlu indeks dalam iterasi? Anda bisa menggunakan Array.entries():

for (const [index, el] of arr.entries()) {
  if ( index === 5 ) break;
}
canac
sumber
4
@superhero Anda bisa mendapatkan indeks elemen dalam untuk ... dari loop, Anda hanya perlu menggunakan entries. untuk (const [indeks, elemen] someArray.entries ()) {// ...}
blackxored
bukankah disarankan untuk tidak menggunakan untuk ... dengan array?
schehata
4
@emostafa Anda benar karena dalam loop tidak direkomendasikan untuk array, tetapi pendekatan ini sebenarnya menggunakan for of loop.
canac
Ini "untuk dari", dan ini adalah solusi yang sangat bersih ... tetapi ini juga merupakan fitur ES6, jadi perlu diketahui bahwa ini hanya akan berfungsi jika lingkungan Anda diatur untuk ES6.
Chad
Saya menemukan diri saya menggunakan solusi ini banyak, dan saya menggunakannya untuk objek juga. Dengan objek, Anda bisa melakukannya Object.entries(myObject)dan menggunakannya persis seperti yang Anda gunakan for..inuntuk array. Perhatikan bahwa array JS pada dasarnya adalah objek di bawah tenda: blog.niftysnippets.org/2011/01/myth-of-arrays.html
Andrew
204

Anda dapat menggunakan setiap metode:

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

ES6

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

untuk penggunaan dukungan browser lama:

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

lebih detail di sini .

Valdemar_Rudolfovich
sumber
10
Bagus dan bersih di ES6 sekarang -[1,2,3].every( el => el !== 1 )
metame
1
@Valdemar, Tetapi apakah every menjamin bahwa panggilan dilakukan secara berurutan?
Pacerier
4
@Pacerier, Anda dapat melihat algoritme dalam spesifikasi ES6 yang kdimulai dengan indeks 0 dan bertambah 1: http://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.every
XP1
@ XP1, Apakah semua implementator harus melakukannya dengan cara itu?
Pacerier
1
@Pacerier, ya, implementasi paling populer berfungsi dengan baik. Jika Anda khawatir tentang implementasi yang disematkan, biasanya itu Opera atau webkit. Metode setiap panggilan callbackfn satu kali untuk setiap elemen yang ada dalam array, dalam urutan naik , sampai menemukan satu di mana callbackfn mengembalikan false. Lihat juga langkah 7. Biarkan k menjadi 0. dan 8.e Tingkatkan k oleh 1.
Valdemar_Rudolfovich
78

Mengutip dari dokumentasi MDN tentangArray.prototype.forEach() :

Tidak ada cara untuk menghentikan atau menghancurkan sebuah forEach()lingkaran selain dengan melemparkan pengecualian. Jika Anda memerlukan perilaku seperti itu, .forEach()metode ini adalah alat yang salah , gunakan loop sederhana sebagai gantinya. Jika Anda menguji elemen array untuk predikat dan membutuhkan nilai balik boolean, Anda bisa menggunakan every()atau some()sebagai gantinya.

Untuk kode Anda (dalam pertanyaan), seperti yang disarankan oleh @bobince, gunakan Array.prototype.some()saja. Ini sangat cocok untuk penggunaan Anda.

Array.prototype.some()mengeksekusi fungsi callback sekali untuk setiap elemen yang ada dalam array sampai ia menemukan satu di mana callback mengembalikan nilai yang sebenarnya (nilai yang menjadi benar ketika dikonversi ke a Boolean). Jika elemen tersebut ditemukan, some()segera mengembalikan true. Jika tidak, some()mengembalikan false. callback dipanggil hanya untuk indeks array yang telah menetapkan nilai; itu tidak dipanggil untuk indeks yang telah dihapus atau yang tidak pernah diberi nilai.

Rahul Desai
sumber
1
Ini jawaban yang benar. 'beberapa' melakukan persis seperti apa yang akan dilakukan pendahuluan / istirahat. Itu loop sampai iterasi n = true.
Antony Booth
74

Sayangnya dalam hal ini akan jauh lebih baik jika Anda tidak menggunakannya forEach. Alih-alih menggunakan forloop reguler dan sekarang akan bekerja persis seperti yang Anda harapkan.

var array = [1, 2, 3];
for (var i = 0; i < array.length; i++) {
  if (array[i] === 1){
    break;
  }
}
Weston Ganger
sumber
27
Ini mengejutkan saya bahwa suara tertinggi adalah implementasi terburuk yang mungkin, dibandingkan dengan performa tinggi, kode lebih sedikit, dan keterbacaan yang lebih baik dari jawaban yang benar ini. Melempar pengecualian ... benarkah? Apakah tradisional untuk loop tidak cukup kewl?
gdbj
2
@ gdbj Saya setuju dengan pernyataan Anda dan menggunakan metode ini, tetapi yang benar-benar mengejutkan saya adalah tidak ada cara untuk keluar dari forEach tanpa peretasan ini, sekarang itu desain yang buruk.
ScottN
28

Pertimbangkan untuk menggunakan jquery's eachmetode, karena memungkinkan untuk mengembalikan fungsi dalam callback palsu:

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

Perpustakaan Lodash juga menyediakan takeWhilemetode yang dapat dirantai dengan peta / perkecil / lipat dll:

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');
// => []
Vittore
sumber
1
Alasan bagus untuk menggunakan jQuery. forEach di javascript asli masih kurang.
Alex Grande
3
@AlexGrande forEach dan forEach JavaScript dari jQuery tidak kompatibel.
Bjorn
10
JavaScript digunakan di banyak tempat yang jQuery bukan opsi.
JBRWilkinson
18

Jika Anda ingin menggunakan saran Dean Edward dan melemparkan kesalahan StopIteration untuk keluar dari loop tanpa harus menangkap kesalahan, Anda dapat menggunakan fungsi berikut ( asal dari sini ):

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

Kode di atas akan memberi Anda kemampuan untuk menjalankan kode seperti berikut tanpa harus melakukan klausa coba-coba Anda sendiri:

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

Satu hal penting untuk diingat adalah bahwa ini hanya akan memperbarui fungsi Array.prototype.forEach jika sudah ada. Jika belum ada, itu tidak akan memodifikasinya.

Chris West
sumber
11

Jawaban singkat: gunakan for...breakuntuk ini atau ubah kode Anda untuk menghindari pemecahan forEach. Jangan gunakan .some()atau .every()untuk ditiru for...break. Tulis ulang kode Anda untuk menghindari for...breakperulangan, atau gunakan for...break. Setiap kali Anda menggunakan metode ini sebagaifor...break alternatif, Tuhan membunuh anak kucing.

Jawaban panjang:

.some()dan .every()keduanya mengembalikan booleannilai, .some()mengembalikan truejika ada elemen yang fungsinya lewat kembali true, setiap pengembalian falsejika ada elemen yang fungsinya lewat kembalifalse . Inilah yang dimaksud fungsi. Menggunakan fungsi untuk apa yang tidak mereka maksudkan jauh lebih buruk daripada menggunakan tabel untuk tata letak, bukan CSS, karena itu membuat semua orang yang membaca kode Anda frustrasi.

Juga, satu-satunya cara yang mungkin untuk menggunakan metode ini sebagai for...breakalternatif adalah dengan membuat efek samping (mengubah beberapa vars di luar .some()fungsi callback), dan ini tidak jauh berbeda for...break.

Jadi, menggunakan .some()atau .every()sebagai for...breakalternatif loop tidak bebas dari efek samping, ini tidak jauh lebih bersihfor...break , ini membuat frustrasi, jadi ini tidak lebih baik.

Anda selalu dapat menulis ulang kode Anda sehingga tidak perlu ada for...break. Anda dapat memfilter array menggunakan .filter(), Anda dapat membagi array menggunakan .slice()dan sebagainya, lalu menggunakan .forEach()atau .map()untuk bagian array itu.

Maks
sumber
menggunakan .filter sebenarnya adalah solusi yang tepat untuk banyak kasus penggunaan untuk melanggar.
TKoL
Bagaimana dengan kinerja? Tidakkah filter memengaruhi kinerja jika sering digunakan?
tfrascaroli
Ya, prototipe array filter bisa menjadi berat. Saya suka, tapi itu bisa mempengaruhi kinerja jika terlalu sering digunakan.
Chad
@ tfrascaroli gunakan for...breakperulangan jika Anda membutuhkan kinerja. forloop yang paling alat performant iterasi dari .forEach(), .any(), .map(), .filter()dll
Max
6

Ini adalah sesuatu yang saya buat untuk menyelesaikan masalah ... Saya cukup yakin ini memperbaiki masalah yang dimiliki oleh penanya semula:

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

Dan kemudian Anda akan menyebutnya dengan menggunakan:

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

Mengembalikan salah di dalam fungsi panggilan balik akan menyebabkan jeda. Beri tahu saya jika itu tidak berhasil.

tennisgent
sumber
1
=== falsemungkin lebih baik daripada == falseitu Anda tidak harus secara eksplisit mengembalikan true (atau nilai kebenaran) untuk melanjutkan loop, jangan sampai beberapa jalur kontrol tidak mengembalikan nilai dan loop rusak secara tak terduga.
Jake
6

Konsep lain yang saya kemukakan adalah:

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

c24w
sumber
Sintaksnya mirip dengan [NSArray enumerateObjectsUsingBlock], Terima kasih!
Chrstph SLN
@Drenai tanda tangan analog dengan aslinya Array.prototype.forEach(). fordan breakada jauh sebelum pertanyaan ini diajukan; OP sedang mencari perilaku itu menggunakan, lebih fungsional forEach,.
c24w
@Drenai sekarang telah menghapus komentar mereka (tetapi meninggalkan downvote) yang menyebutkan bahwa tanda tangan dari solusi ini sulit untuk diingat dan tidak perlu ketika Anda dapat menyelesaikan masalah dengan for...indan break.
c24w
6
var array = [1,2,3,4];

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

Menemukan solusi ini di situs lain. Anda bisa membungkus forEach dalam skenario coba / tangkap.

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

Lebih detail di sini: http://dean.edwards.name/weblog/2006/07/enum/

RussellUresti
sumber
2
Jangan gunakan pengecualian sebagai pernyataan aliran kontrol. Gunakan untuk menangani hasil yang tidak terduga.
Maks
4

Jika Anda tidak perlu mengakses array Anda setelah iterasi, Anda dapat menebus dengan menetapkan panjang array menjadi 0. Jika Anda masih membutuhkannya setelah iterasi Anda, Anda dapat mengkloningnya menggunakan slice ..

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

Atau dengan klon:

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

Yang merupakan solusi yang jauh lebih baik daripada melemparkan kesalahan acak dalam kode Anda.

3rdEden
sumber
dilakukan dengan baik :) tetapi jika ada beberapa tindakan setelah penetapan array.lengthke 0mereka akan berlaku dalam iterasi saat ini, jadi mungkin kadang-kadang lebih baik untuk digunakan returnsetelah penetapan tersebut
zhibirc
4

Ini adalah untuk loop, tetapi mempertahankan referensi objek dalam loop seperti forEach () tetapi Anda bisa keluar.

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

Seperti yang disebutkan sebelumnya, Anda tidak dapat merusak .forEach().

Inilah cara yang sedikit lebih modern untuk melakukan foreach dengan ES6 Iterators. Memungkinkan Anda mendapatkan akses langsung ke index/ valuesaat iterasi.

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

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

Keluaran:

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

Tautan

Alex
sumber
3

Namun pendekatan lain

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

Saya menggunakan nullhack untuk tujuan itu, ia mencoba mengakses properti null, yang merupakan kesalahan:

try {
  [1,2,3,4,5]
  .forEach(
    function ( val, idx, arr ) {
      if ( val == 3 ) null.NULLBREAK;
    }
  );
} catch (e) {
  // e <=> TypeError: null has no properties
}
//
pengesampingan publik
sumber
1
Kenapa tidak adil throw BREAK?
Bergi
1

Jika Anda ingin menyimpannya forEach sintaks , ini adalah cara untuk membuatnya tetap efisien (meskipun tidak sebagus reguler untuk loop). Periksa segera untuk variabel yang tahu jika Anda ingin keluar dari loop.

Contoh ini menggunakan fungsi anonim untuk membuat lingkup fungsi di forEachmana Anda perlu menyimpan informasi yang dilakukan .

(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>

Dua sen saya.

Justus Romijn
sumber
1

Saya tahu itu bukan cara yang benar. Itu tidak mematahkan loop. Itu adalah Jugad

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

Durgpal Singh
sumber
0

Setuju dengan @bobince, terunggah.

Juga, FYI:

Prototype.js memiliki sesuatu untuk tujuan ini:

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

$break akan ditangkap dan ditangani oleh Prototype.js secara internal, memutus siklus "masing-masing" tetapi tidak menghasilkan kesalahan eksternal.

Lihat Prototype.JS API untuk detailnya.

jQuery juga memiliki caranya, kembalikan false di handler untuk memutus loop awal:

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

  });
</script>

Lihat jQuery API untuk detailnya.

Dmitri Sologoubenko
sumber
0

Ini bukan yang paling efisien, karena Anda masih menggilir semua elemen, tapi saya pikir mungkin ada baiknya mempertimbangkan yang sangat sederhana:

let keepGoing = true;
things.forEach( (thing) => {
  if (noMore) keepGoing = false;
  if (keepGoing) {
     // do things with thing
  }
});
martir
sumber
continueadalah kata kunci, kode Anda adalah kesalahan sintaksis.
Bergi
3
Mengingat bahwa Anda tetap menggunakan ES6, Anda hanya perlu beralih ke for ofloop dan break;dari itu seperti biasa.
Bergi
tetap, dan benar - tetapi sebagian besar menggunakan es6 untuk singkatnya
martyman
0

Anda dapat mengikuti kode di bawah ini yang berfungsi untuk saya:

 var     loopStop = false;
YOUR_ARRAY.forEach(function loop(){
    if(loopStop){ return; }
    if(condition){ loopStop = true; }
});
BERGUIGA Mohamed Amine
sumber
Kenapa -1? itu tidak lebih buruk daripada menangkap pengecualian, itu adalah IMHO hack yang lebih besar.
Byron Whitlock
0

Saya lebih suka menggunakan 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 inberfungsi seperti ini forEach, dan Anda dapat menambahkan kembali ke fungsi keluar di dalamnya. Performa yang lebih baik juga.

Jorge Alberto
sumber
0

Jika Anda perlu memecah berdasarkan nilai elemen yang sudah ada di array Anda seperti dalam kasus Anda (yaitu jika kondisi break tidak tergantung pada variabel run-time yang dapat berubah setelah array diberi nilai elemennya) Anda juga bisa menggunakan kombinasi dari slice () dan indexOf () sebagai berikut.

Jika Anda perlu istirahat ketika untuk setiap mencapai 'Apple' yang dapat Anda gunakan

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

Sebagaimana dinyatakan dalam W3Schools.com metode slice () mengembalikan elemen yang dipilih dalam array, sebagai objek array baru. Array asli tidak akan diubah.

Lihat di JSFiddle

Semoga ini bisa membantu seseorang.

Ula
sumber
0

Anda dapat membuat varian dari forEachyang memungkinkan untuk break, continue, return, dan bahkan async/ await: (contoh ditulis dalam naskah)

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

Pemakaian:

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);
}
Venryx
sumber
-1

coba dengan "temukan":

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" }
GigolNet Guigolachvili
sumber
-1

Ya mungkin untuk melanjutkan dan keluar dari loop forEach.

Untuk melanjutkan, Anda dapat menggunakan kembali, loop akan melanjutkan tetapi fungsi saat ini akan berakhir.

Untuk keluar dari loop, Anda dapat mengatur parameter ketiga ke 0 panjang, atur ke array kosong. Loop tidak akan melanjutkan, fungsi saat ini dilakukan, sehingga Anda dapat menggunakan "kembali" untuk menyelesaikan, seperti keluar dalam normal untuk loop ...

Ini:

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

akan mencetak ini:

1
next... 0
2
next... 1
3
4
next... 3
5
Luis Marin
sumber
-2

Sebelumnya, kode saya ada di bawah

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

                    return false;
                }
            });

Saya telah mengubah ke bawah, ini diperbaiki.

 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;
                }
            }
Metin Atalay
sumber