ขั้นตอนการควบคุม

โฟลว์การควบคุมคือลำดับที่ล่าม JavaScript เรียกใช้ ข้อความ หากสคริปต์ไม่รวมคำสั่งที่เปลี่ยนขั้นตอน ดำเนินการตั้งแต่ต้นจนจบ ทีละบรรทัด โครงสร้างการควบคุม ใช้ในการพิจารณาว่าชุดคำสั่งจะได้รับการดำเนินการโดยอิงตาม ชุดของเกณฑ์ที่กำหนดไว้ ดำเนินการตามชุดคำสั่งซ้ำๆ หรือขัดจังหวะ ลำดับของข้อความ

คำสั่งแบบมีเงื่อนไขจะกำหนดว่าควรเรียกใช้โค้ดจากโค้ด เงื่อนไขเพิ่มเติม คำสั่งแบบมีเงื่อนไขจะเรียกใช้โค้ดที่อยู่ในโค้ดหาก เงื่อนไขที่เกี่ยวข้อง (หรือชุดเงื่อนไข) จะประเมินเป็น true มิเช่นนั้น แอตทริบิวต์ ข้ามรหัส

ifelse

คำสั่ง if จะประเมินเงื่อนไขภายในวงเล็บที่ตรงกันซึ่ง ติดตาม หากเงื่อนไขภายในวงเล็บประเมินเป็น true พารามิเตอร์ คำสั่งหรือคำสั่งบล็อก ที่อยู่หลังวงเล็บที่ตรงกันจะได้รับการดำเนินการ:

if ( true ) console.log( "True." );
> "True."

if ( true ) {
   
const myString = "True.";
    console
.log( myString );
}
> "True."

หากเงื่อนไขภายในวงเล็บประเมินเป็น false คำสั่งที่ ติดตามเลยจะถูกละเว้น

if ( false ) console.log( "True." );

คีย์เวิร์ด else ที่ตามหลังคำสั่ง if และ คำสั่งที่ดำเนินการแบบมีเงื่อนไขจะระบุคำสั่งที่จะดำเนินการหาก เงื่อนไข if ประเมินได้เป็น false:

if ( false ) console.log( "True." )''
else console.log( "False" );
> "False."

หากต้องการเชื่อมโยงคำสั่ง if หลายรายการเข้าด้วยกัน คุณสามารถสร้างเมธอด คำสั่งที่ดำเนินการอย่างมีเงื่อนไขตามคำสั่ง if อีก else รายการ:

const myCondition = 2;
if ( myCondition === 5 ) console.log( "Five." );
else if ( myCondition === 2 ) console.log( "Two." );

เราขอแนะนำให้ใช้ไวยากรณ์คำสั่งบล็อกต่อไปนี้ตามเงื่อนไขเพื่อ ปรับปรุงข้อความให้อ่านง่ายขึ้น แต่ข้อความ else if มักมีข้อยกเว้นสำหรับกรณีต่อไปนี้

if ( myCondition === 5 ) {
    console
.log( "Five." );
} else if ( myCondition === 3 ) {
    console
.log( "Three" );
} else {
    console
.log( "Neither five nor three." );
}
> "Neither five nor three."

โอเปอเรเตอร์สามส่วน

if ดำเนินการตามคำสั่งอย่างมีเงื่อนไข โอเปอเรเตอร์สามส่วน (แม่นยำกว่า แต่ไม่ค่อยเรียกว่าโอเปอเรเตอร์แบบมีเงื่อนไขสามส่วน) เป็นชวเลข เพื่อเรียกใช้นิพจน์อย่างมีเงื่อนไข ตามชื่อที่บอกก็คือ เทอร์นารี คือโอเปอเรเตอร์ JavaScript เพียงตัวเดียวที่ใช้โอเปอแรนด์ 3 ตัว

  • เงื่อนไขที่ต้องการประเมิน ตามด้วยเครื่องหมายคำถาม (?)
  • นิพจน์ที่จะดำเนินการหากเงื่อนไขประเมินเป็น true ตามด้วย เครื่องหมายโคลอน (:)
  • นิพจน์ที่จะดำเนินการหากเงื่อนไขประเมินเป็น false

ตัวเลือกนี้ใช้บ่อยเพื่อตั้งค่าหรือส่งค่าแบบมีเงื่อนไข

const myFirstResult  = true  ? "First value." : "Second value.";
const mySecondResult = false ? "First value." : "Second value.";

myFirstResult
;
> "First value."

mySecondResult
;
> "Second value."

switchcase

ใช้คำสั่ง switch เพื่อเปรียบเทียบค่าของนิพจน์กับรายการของ ค่าที่เป็นไปได้ที่กำหนดโดยใช้คีย์เวิร์ด case คำขึ้นไป ไวยากรณ์นี้คือ เพราะมาจากการตัดสินใจด้านการออกแบบแรกสุดของ JavaScript ไวยากรณ์ switch...case ใช้คีย์เวิร์ด switch ตามด้วยนิพจน์เพื่อ อยู่ในวงเล็บแล้วตามด้วยวงเล็บปีกกาคู่ที่ตรงกัน ส่วนเนื้อหาของ switch จะมีคีย์เวิร์ดได้ case คำ ซึ่งโดยปกติแล้ว ตามด้วยนิพจน์หรือค่า ตามด้วยเครื่องหมายทวิภาค (:)

เมื่อล่ามเข้าถึง case ที่มีค่าตรงกับนิพจน์ที่ระบุ ประเมินไว้ในวงเล็บหลังคีย์เวิร์ด switch คีย์เวิร์ดจะประมวลผล ข้อความที่เป็นไปตามวรรค case นั้น:

switch ( 2 + 2 === 4 ) {
 
case false:
    console
.log( "False." );
 
case true:
    console
.log( "True." );
}
> "True."

คำสั่งทั้งหมดที่อยู่หลัง case ที่ตรงกันจะถูกดำเนินการแม้ว่าจะมีการ ซึ่งระบุไว้ในคำสั่งบล็อก

switch ( 2 + 2 === 4 ) {
   
case false:
    console
.log( "False." );
 
case true:
    let myVariable
= "True.";
    console
.log( myVariable );

}
> "True."

ข้อผิดพลาดอย่างหนึ่งของการใช้ switch…case ก็คือ หลังจากพบรายการที่ตรงกันแล้ว ล่าม JavaScript จะเรียกใช้คำสั่งใดก็ได้ที่ตามหลัง case ที่ตรงกัน แม้แต่ภายในวรรคอื่นๆ ของ case สิ่งนี้เรียกว่า "การผ่าน" ไปยัง case ถัดไป:

switch ( 2 + 2 === 7 ) {
   
case false:
    console
.log( "False." );
 
case true:
    console
.log( "True." );
}
> "False."
> "True."

เพื่อป้องกันไม่ให้เกิดข้อผิดพลาด โปรดจบแต่ละกรณีด้วยคีย์เวิร์ด break ซึ่ง หยุดการประเมินเนื้อหาของ switch ทันที:

switch ( 2 + 2 === 7 ) {
   
case false:
    console
.log( "False." );
   
break;
 
case true:
    console
.log( "True." );
   
break;
}
> "False."

หากไม่มี case ที่ตรงกับค่าแบบมีเงื่อนไข switch จะเลือก default ถ้ามี:

switch ( 20 ) {
   
case 5:
    console
.log( "The value was five." );
   
break;
 
case 10:
    console
.log( "The value was ten." );
   
break;
 
default:
    console
.log( "The value was something unexpected." );
}
> "The value was something unexpected."

อย่างไรก็ตาม รายได้ที่ลดลงจะมีผลกับ default ด้วยเช่นกัน ซึ่งอาจทําให้ ผลลัพธ์ที่ไม่คาดคิด หากต้องการแก้ไขปัญหานี้ ให้สิ้นสุดใบแจ้งยอด default ด้วย break หรือวางไว้ลำดับสุดท้ายในรายการกรณี

switch ( 20 ) {
 
default:
    console
.log( "The value was something unexpected." );
 
case 10:
    console
.log( "The value was ten." );
   
break;
 
case 5:
    console
.log( "The value was five." );
   
break;
}
> The value was something unexpected.
> The value was ten.

เนื่องจากวลีของ case ไม่กำหนดให้มี บล็อกคำสั่งสำหรับการจัดกลุ่ม คำสั่งหลายรายการ วลี case และ default ไม่สร้าง ขอบเขตคำศัพท์เพียงอย่างเดียว:

let myVariable;
switch ( true ) {
 
case true:
    let myVariable
= "True.";
   
break;
 
default:
    let myVariable
= "False.";
   
break;
}
> Uncaught SyntaxError: redeclaration of let myVariable

หากต้องการจัดการขอบเขต ให้ใช้คำสั่งบล็อกดังนี้

let myVariable;
switch ( true ) {
 
case true: {
    let myVariable
= "True.";
   
break;
 
}
 
default: {
    let myVariable
= "False.";
   
break;
 
}
}

การวนซ้ำและการทำซ้ำ

การวนซ้ำช่วยให้คุณดำเนินการกับชุดคำสั่งซ้ำตราบเท่าที่เป็นไปตามเงื่อนไข หรือ จนกว่าจะตรงตามเงื่อนไข ใช้การวนซ้ำเพื่อดำเนินการชุดคำสั่งแบบคงที่ จำนวนครั้งจนกว่าจะบรรลุผลที่ชัดเจน หรือจนกว่าล่าม ถึงจุดสิ้นสุดของโครงสร้างข้อมูลที่สามารถทำซ้ำได้ (ตัวอย่างเช่น องค์ประกอบสุดท้ายใน อาร์เรย์ แผนที่ หรือชุด คุณสมบัติสุดท้ายของวัตถุ หรืออักขระตัวสุดท้ายใน สตริง)

ลูปรบกวนการตั้งค่า "จากบนลงล่าง" ขั้นตอนการดำเนินการของสคริปต์โดยทำซ้ำ ในชุดคำสั่งจนกว่าจะเป็นไปตามเงื่อนไขอย่างน้อย 1 ข้อ หรือ ขึ้นอยู่กับไวยากรณ์ที่ใช้สร้างลูป หลังจากสิ้นสุดการวนซ้ำ ข้อความจะดำเนินต่อไปเรื่อยๆ ตามคำสั่งนั้น ในตัวอย่างต่อไปนี้ คำสั่งในส่วนเนื้อหาของลูปจะดำเนินการ 3 ครั้งก่อน ล่ามต่อไป:

let iterationCount = 0;
console
.log( "Pre-loop." );
while( iterationCount < 3 ) {
  iterationCount
++;
  console
.log( "Loop iteration." );
}
console
.log( "Continuing on." );
> "Pre-loop."
> "Loop iteration."
> "Loop iteration."
> "Loop iteration."
> "Continuing on."

หากไม่สามารถตรงตามเงื่อนไขในระหว่างการดำเนินการของลูป ลูปจะดำเนินต่อไป ไปเรื่อยๆ การวนลูปที่ไม่สิ้นสุดเหล่านี้เป็นข้อผิดพลาดที่พบได้บ่อยในการเขียนโปรแกรมที่อาจ ทำให้เทรดการดำเนินการหลัก หยุดชั่วคราวโดยไม่มีกำหนด หรือแม้แต่ทำให้แท็บเบราว์เซอร์ขัดข้อง

ตัวอย่างต่อไปนี้จะทำงานตราบเท่าที่ค่าบูลีน true ยังคงอยู่ true เนื่องจากค่าบูลีนจะเปลี่ยนแปลงไม่ได้ ก็จะสร้างลูปที่ไม่สิ้นสุด

console.log( "Pre-loop." );
while( true ) {
console
.log( "Loop iteration." );
}
> "Pre-loop."
> "Loop iteration."
> "Loop iteration."
> "Loop iteration."
> "Loop iteration."
> "Loop iteration."

หลีกเลี่ยงการวนซ้ำแบบไม่สิ้นสุดในโค้ดการผลิต หากคุณสร้าง ระหว่างการพัฒนา คุณสามารถแก้ไขได้ด้วยการปิดแท็บเบราว์เซอร์ที่แท็บทำงานอยู่ อัปเดตโค้ดเพื่อไม่ให้การวนซ้ำไม่มีที่สิ้นสุดอีกต่อไป และเปิด

while

ลูป while สร้างขึ้นโดยใช้คีย์เวิร์ด while ตามด้วยคู่ของ วงเล็บที่ตรงกับเงื่อนไขที่ต้องประเมิน หากระบุ จะพิจารณาในเบื้องต้นเป็น true คำสั่ง (หรือ ข้อความบล็อก) ที่ตามมา ระบบจะดำเนินการกับวงเล็บเหล่านั้น หากไม่ ลูปจะไม่ทำงาน หลังแต่ละรายการ การทำซ้ำ ระบบจะประเมินเงื่อนไขอีกครั้ง และหากยังคงเป็น true จะเกิดการวนซ้ำ ซ้ำ

let iterationCount = 0;
while( iterationCount < 3 ) {
  iterationCount
++;
  console
.log( `Loop ${ iterationCount }.` );
}
> "Loop 1."
> "Loop 2."

หากล่ามพบคำสั่ง continue ในลูป while ระบบจะหยุดการทำงานดังกล่าว ทำซ้ำ ประเมินเงื่อนไขอีกครั้ง และดำเนินการวนซ้ำหากเป็นไปได้

let iterationCount = 0;
while( iterationCount <= 5 ) {
  iterationCount
++;
 
if( iterationCount === 3 ) {
   
continue;
 
}
  console
.log( `Loop ${ iterationCount }.` );
}
console
.log( "Loop ended." );
> "Loop 1."
> "Loop 2."
> "Loop 4."
> "Loop 5."
> "Loop ended."

หากล่ามพบคำสั่ง break ในลูป while การทำซ้ำนั้น และจะไม่ได้รับการประเมินเงื่อนไขอีกครั้ง ซึ่งจะทำให้ล่ามทำงานต่อไป

let iterationCount = 1;
while( iterationCount <= 5 ) {
 
if( iterationCount === 3 ) {
    console
.log(`Iteration skipped.``);`
   
break;
 
}
  console
.log( `Loop ${ iterationCount }.` );
  iterationCount
++;
}
console
.log( "Loop ended." );
> "Loop 1."
> "Loop 2."
> "Iteration skipped.
> "
Loop ended."

คุณสามารถใช้ while เพื่อทำซ้ำเป็นจำนวนครั้งที่ระบุ ดังที่แสดงใน ตัวอย่างก่อนหน้านี้ แต่กรณีการใช้งานที่พบบ่อยที่สุดสำหรับ while ก็คือการวนซ้ำ ความยาวไม่จำกัด:

let randomize = () => Math.floor( Math.random() * 10 );
let randomNum
= randomize();
while( randomNum !== 3 ){
  console
.log( `The number is not ${ randomNum }.` );
  randomNum
= randomize();
}
console
.log( `The correct number, ${ randomNum }, was found.` );
> "The number is not 0."
> "The number is not 6."
> "The number is not 1."
> "The number is not 8."
> "The correct number, 3, was found."

dowhile

do...while เป็นตัวแปรของลูป while ที่มีเงื่อนไข การประเมินจะเกิดขึ้นในช่วงสิ้นสุดของการวนซ้ำแต่ละครั้ง ซึ่งหมายความว่า จะดำเนินการกับเนื้อหาของลูปอย่างน้อย 1 ครั้งเสมอ

หากต้องการสร้างลูป do...while ให้ใช้คีย์เวิร์ด do ตามด้วยคำสั่ง (หรือคำสั่งบล็อก) เป็น ดำเนินการกับการวนซ้ำแต่ละครั้ง เพิ่มทันทีหลังจากข้อความดังกล่าว while และวงเล็บที่ตรงกันซึ่งมีเงื่อนไขที่จะต้องประเมิน วันและเวลา เงื่อนไขนี้จะไม่ประเมินผลเป็น true อีกต่อไป การวนซ้ำจะสิ้นสุดลง

let iterationCount = 1;
do {
  console
.log( `Loop ${ iterationCount }.` );
  iterationCount
++;
} while ( iterationCount < 3 );
> "Loop 1."
> "Loop 2."
> "Loop 3."

เช่นเดียวกับการวนซ้ำ while กรณีการใช้งานที่พบบ่อยที่สุดสำหรับ do...while คือลูป ความยาวไม่จำกัด:

let randomNum;
do {
  randomNum
= ( () => Math.floor( Math.random() * 10 ) )();
  console
.log( `Is the number ${ randomNum }?` );
} while ( randomNum !== 3 );
console
.log( `Yes, ${ randomNum } was the correct number.` );
> "Is the number 9?"
> "Is the number 2?"
> "Is the number 8?"
> "Is the number 2?"
> "Is the number 3?"
> "Yes, 3 was the correct number."

for

ใช้การวนซ้ำ for เพื่อวนซ้ำจำนวนที่ทราบ ในโค้ดเบสเดิม ที่ใช้บ่อยเพื่อทำซ้ำองค์ประกอบในอาร์เรย์

หากต้องการสร้างลูป for ให้ใช้คีย์เวิร์ด for ตามด้วยชุดวงเล็บ ที่ยอมรับนิพจน์ 3 รายการต่อไปนี้ตามลำดับและคั่นด้วย เครื่องหมายเซมิโคลอน:

  1. นิพจน์ที่จะประเมินเมื่อเริ่มวนซ้ำ
  2. เงื่อนไขที่กําหนดว่าควรวนซ้ำต่อหรือไม่
  3. นิพจน์ที่จะดำเนินการเมื่อสิ้นสุดแต่ละลูป

หลังวงเล็บเหล่านี้ ให้เพิ่มคำสั่ง (โดยทั่วไปคือ คำสั่งบล็อก) เป็น เรียกใช้ในระหว่างการวนซ้ำ

for( let i = 0; i < 3; i++ ) {
  console
.log( "This loop will run three times.")
}

นิพจน์แรกจะเริ่มต้นตัวแปรที่ทำหน้าที่เป็นตัวนับ ช่วงเวลานี้ นิพจน์จะได้รับการประเมินครั้งเดียว ก่อนการวนซ้ำครั้งแรก คุณสามารถ เริ่มต้นตัวแปรนี้โดยใช้ let (หรือ var ย้อนหลัง) เช่นเดียวกับอื่นๆ และขอบเขตคือเนื้อหาของลูป ตัวแปรเหล่านี้สามารถมี ตัวระบุที่ถูกต้อง แต่มักใช้เรียก i สำหรับ "การทำซ้ำ" หรือ "index" ดูเหมือนว่าจะขัดแย้งกับ แนวทางปฏิบัติแนะนำสำหรับชื่อตัวระบุที่คาดการณ์ได้ แต่ธรรมเนียมปฏิบัติมีมาอย่างดีเพียงพอที่จะทำให้นักพัฒนาซอฟต์แวร์รายอื่นๆ เข้าใจได้อย่างชัดเจน เพียงเหลือบตามอง เนื่องจากคอลเล็กชันที่จัดทำดัชนีจะมีการจัดทำดัชนีเป็น 0 ตัวแปรเหล่านี้มักจะมีค่าเริ่มต้นเป็น 0 เกือบทุกครั้ง

เช่นเดียวกับการวนซ้ำรูปแบบอื่นๆ เงื่อนไขคือนิพจน์ที่กำหนด ควรเรียกใช้การวนซ้ำหรือไม่ ซึ่งมักจะใช้เพื่อตั้งค่า ที่กำหนดไว้สำหรับตัวนับการทำซ้ำ ล่ามจะประเมินสภาพก่อน กำลังเรียกใช้ลูป for เป็นครั้งแรก หากเงื่อนไขไม่เริ่มต้นตั้งแต่แรก ประเมินเป็น true จะไม่มีการดำเนินการส่วนเนื้อหาของลูป

นิพจน์สุดท้ายจะทำงานเมื่อสิ้นสุดการทำซ้ำแต่ละครั้งผ่านลูป โดยปกติแล้วจะใช้เพื่อเพิ่มตัวระบุทีละ 1 รายการ

คุณจะเห็นการวนซ้ำ for ที่เกิดซ้ำผ่านอาร์เรย์ในเวอร์ชันเก่า ฐานของโค้ด ในกรณีเหล่านี้ เงื่อนไขที่ระบุไว้เพื่อการวนซ้ำต่อคือ จำนวนการทำซ้ำน้อยกว่าหรือเท่ากับความยาวของอาร์เรย์ที่จะทำซ้ำ ถึง ตัวแปรที่ใช้ติดตามจำนวนการทำซ้ำปัจจุบันจะใช้เพื่อดู เพิ่มค่าที่เชื่อมโยงกับดัชนีดังกล่าวในอาร์เรย์ ซึ่งจะทำให้แต่ละองค์ประกอบใน อาร์เรย์ที่จะดำเนินการตามลำดับ

var myArray = [ true, false, true ];
for( let i = 0; i <= myArray.length; i++ ) {
  console
.log( myArray[ i ] );
}
> true
> false
> true

เลิกใช้แนวทางนี้แล้วเพื่อเปลี่ยนไปใช้แนวทางที่ทันสมัยกว่าในการ วนซ้ำโครงสร้างข้อมูลที่สร้างขึ้นได้

for [...] of [...]

ใช้การวนซ้ำ for...of... เพื่อทำซ้ำค่าที่เก็บไว้ใน โครงสร้างข้อมูลที่ทำซ้ำได้ เช่น อาร์เรย์ ชุด หรือแผนที่

ลูป for...of... ใช้คีย์เวิร์ด for ตามด้วยวงเล็บชุด ที่มีตัวแปร ตามด้วย of จากนั้นจึงจะทำซ้ำโครงสร้างข้อมูล ใหม่ คุณสามารถประกาศตัวแปรที่นี่โดยใช้ let, const หรือ var ซึ่งเป็นตัวแปรที่ประกาศไปก่อนหน้านี้ภายในขอบเขตปัจจุบัน เป็นออบเจ็กต์ หรืออินสแตนซ์ของ ที่ทำลายการมอบหมายนี้ ซึ่งประกอบด้วยค่าขององค์ประกอบที่สอดคล้องกับการทำซ้ำปัจจุบัน ของการวนซ้ำ

const myIterable = [ true, false, true ];
for( const myElement of myIterable ) {
  console
.log( myElement );
}
> true
> false
> true

ในตัวอย่างนี้ การใช้ const สำหรับ myElement จะทำงานแม้ว่า myElement จะเป็น ได้รับค่าใหม่ในการวนซ้ำแต่ละครั้ง เนื่องจากตัวแปร ที่ประกาศด้วย let หรือ const จะกำหนดขอบเขตเฉพาะคำสั่งบล็อกภายใน วนซ้ำ ระบบจะเริ่มต้นตัวแปรเมื่อเริ่มต้นการทำซ้ำแต่ละครั้ง และนําออกที่ เมื่อสิ้นสุดการทำซ้ำๆ

forin...

ใช้การวนซ้ำ for...in... เพื่อทำซ้ำคุณสมบัติการแจกแจงของออบเจ็กต์ รวมถึงพร็อพเพอร์ตี้ที่สืบทอดมาได้ เช่นเดียวกับการวนซ้ำ for...of... for...in... ลูปใช้คีย์เวิร์ด for ตามด้วยวงเล็บชุด มีตัวแปรที่มีค่าของคีย์พร็อพเพอร์ตี้ที่เกี่ยวข้อง กับการวนซ้ำในปัจจุบัน ตัวแปรนี้จะตามด้วย คีย์เวิร์ด in รายการ ออบเจ็กต์ที่กำลังปรับปรุงใน:

const myObject = { "myProperty" : true, "mySecondProperty" : false };
for( const myKey in myObject ) {
  console
.log( myKey );
}
> "myProperty"
> "mySecondProperty"

แม้ว่าค่า myKey จะเปลี่ยนไปตามการวนซ้ำแต่ละครั้ง คุณสามารถใช้ const โดยไม่มีข้อผิดพลาด เนื่องจากระบบทิ้งตัวแปรได้อย่างมีประสิทธิภาพ เมื่อสิ้นสุดการทำซ้ำแต่ละครั้ง แล้วสร้างใหม่ในช่วงเริ่มต้น

ค่าที่เชื่อมโยงกับคีย์พร็อพเพอร์ตี้แต่ละรายการไม่พร้อมใช้งานโดยตรงสำหรับ ไวยากรณ์ for...in... อย่างไรก็ตาม เนื่องจากลูปเข้าถึงคีย์พร็อพเพอร์ตี้ใน การทำซ้ำแต่ละครั้งได้ คุณสามารถใช้แป้นนั้นเพื่อ "ค้นหา" คุณค่า:

const myObject = { "myProperty" : true, "mySecondProperty" : false };
for( const myKey in myObject ) {
 
const myValue = myObject[ myKey ];
  console
.log( `${ myKey } : ${ myValue }` );
}
> "myProperty : true"
> "mySecondProperty : false"

คุณสมบัติที่สืบทอดมาจากตัวสร้างในตัวจะไม่สามารถแจกแจงได้ ซึ่งหมายความว่า for...in... จะไม่ทำซ้ำผ่านพร็อพเพอร์ตี้ที่รับช่วงมาจาก Object เครื่องมือสร้างขึ้นมา อย่างไรก็ตาม คุณสมบัติที่แจกแจงได้ภายในออบเจ็กต์ ห่วงโซ่ต้นแบบ ได้แก่

const myPrototype = { "protoProperty" : true };
const myObject = Object.create( myPrototype, {
    myProperty
: {
    value
: true,
    enumerable
: true
   
}
});
for ( const myKey in myObject ) {
 
const myValue = myObject[ myKey ];
  console
.log( `${ myKey } : ${ myValue }` );
}
> "myProperty : true"
> "protoProperty : true"

JavaScript มีวิธีในตัวในการกำหนดว่าพร็อพเพอร์ตี้หนึ่งๆ เป็น คุณสมบัติโดยตรงของวัตถุแทนที่จะเป็นคุณสมบัติบนต้นแบบของวัตถุ เชน: สมัยใหม่ Object.hasOwn() และ Object.prototype.hasOwnProperty() เมธอดเดิม เหล่านี้ จะประเมินว่าพร็อพเพอร์ตี้ที่ระบุได้รับมาหรือไม่ (หรือไม่ได้ประกาศ) แสดงผล true เฉพาะสำหรับคุณสมบัติทันทีของออบเจ็กต์ที่ระบุ:

const myPrototype = { "protoProperty" : true };
const myObject = Object.create( myPrototype, {
    myProperty
: {
    value
: true,
    enumerable
: true
   
}
});
for ( const myKey in myObject ) {
 
const myValue = myObject[ myKey ];
 
if ( Object.hasOwn( myObject, myKey ) ) {
    console
.log( `${ myKey } : ${ myValue }` );
 
}
}
> "myProperty : true"

นอกจากนี้ยังมีวิธีแบบคงที่ 3 วิธีซึ่งแต่ละวิธีจะแสดงผลอาร์เรย์ที่ประกอบด้วย คีย์ที่แจกแจงได้ของออบเจ็กต์ (Object.keys()), ค่า (Object.values()) หรือ คู่คีย์-ค่า (Object.entries()):

const myObject = { "myProperty" : true, "mySecondProperty" : false };
Object.keys( myObject );
> Array [ "myProperty", "mySecondProperty" ]

ซึ่งช่วยให้คุณทำซ้ำคีย์ของออบเจ็กต์ ค่า หรือคู่คีย์-ค่าได้ (โดยใช้ การทำลายโครงสร้าง) โดยไม่รวมพร็อพเพอร์ตี้ที่เป็นของต้นแบบของออบเจ็กต์นั้น:

const myPrototype = { "protoProperty" : "Non-enumerable property value." };
const myObject = Object.create( myPrototype, {
    myProperty
: {
    value
: "Enumerable property value.",
    enumerable
: true
   
}
});

for ( const propKey of Object.keys( myObject ) ) {
  console
.log( propKey );
}
> "myProperty"

for ( const propValue of Object.values( myObject ) ) {
  console
.log( propValue );
}
> "Enumerable property value."

for ( const [ propKey, propValue ] of Object.entries( myObject ) ) {
  console
.log( `${ propKey } : ${ propValue }` );
}
> "myProperty : Enumerable property value."

forEach()

เมธอด forEach() ที่ระบุโดยอาร์เรย์ แผนที่ ตั้งค่า และตัวสร้าง NodeList ช่วยสรุปข้อมูลที่มีประโยชน์ในการทำซ้ำข้อมูล ในบริบทของฟังก์ชัน Callback การวนซ้ำแตกต่างจากการวนซ้ำรูปแบบอื่นๆ ลูปที่สร้างด้วยเมธอด forEach() จะไม่สามารถขัดจังหวะได้โดยใช้ break หรือ continue

forEach คือเมธอดที่เป็นของต้นแบบของโครงสร้างข้อมูลแต่ละรายการ แต่ละforEach เมธอดควรมีฟังก์ชัน Callback เป็นอาร์กิวเมนต์ แม้ว่าจะต่างกันเล็กน้อย พจน์ของอาร์กิวเมนต์ที่รวมอยู่เมื่อมีการเรียกใช้ฟังก์ชันนั้น ตัวเลือกที่ 2 ไม่บังคับ ระบุค่า this เพื่อใช้เป็นบริบทการเรียกใช้สำหรับ ฟังก์ชัน Callback

ฟังก์ชัน Callback ที่ใช้กับ Array.forEach จะแสดงพารามิเตอร์ที่มี ค่าขององค์ประกอบปัจจุบัน ดัชนีขององค์ประกอบปัจจุบัน และอาร์เรย์ที่มีการเรียกเมธอด forEach:

const myArray = [ true, false ];
myArray
.forEach( ( myElement, i, originalArray ) => {
  console
.log( i, myElement, originalArray  );
});
> 0 true Array(3) [ true, false ]
> 1 false Array(3) [ true, false ]

ฟังก์ชัน Callback ที่ใช้กับ Map.forEach จะแสดงพารามิเตอร์ที่มีฟังก์ชัน ที่เชื่อมโยงกับองค์ประกอบปัจจุบัน คีย์ที่เชื่อมโยงกับองค์ประกอบปัจจุบัน และแผนที่ที่มีการเรียกเมธอด forEach:

const myMap = new Map([
 
['myKey', true],
 
['mySecondKey', false ],
]);
myMap
.forEach( ( myValue, myKey, originalMap ) => {
    console
.log( myValue, myKey, originalMap  );
});
> true "myKey" Map { myKey true, mySecondKey false }
> false "mySecondKey" Map { myKey true, mySecondKey false }

Callback Set.forEach มีพารามิเตอร์ที่คล้ายกัน เนื่องจากการตั้งค่าไม่มี จัดทำดัชนีหรือคีย์ที่ต่างจากค่า ส่วนอาร์กิวเมนต์ที่สองจะแสดง ซ้ำซ้อน เพิกเฉยได้ อย่างเคร่งครัดเพื่อให้ไวยากรณ์สอดคล้องกับ เมธอด forEach อื่นๆ

const mySet = new Set([ true, false ]);
mySet
.forEach( ( myValue, myKey, originalSet ) => {
  console
.log( myValue, myKey, originalSet  );
});
> true true Set [ true, false ]
> false false Set [ true, false ]

ตัววนซ้ำ

iterable คือโครงสร้างข้อมูลที่ประกอบด้วยองค์ประกอบเดี่ยวๆ ที่สามารถ กล่าวซ้ำถึงการใช้แนวทางโดยละเอียดก่อนหน้านี้ iterator คือ ออบเจ็กต์ที่ทำซ้ำได้ซึ่งเป็นไปตามโปรโตคอล Iterator ซึ่งหมายความว่าต้องใช้ เมธอด next() ที่ล้ำหน้าผ่านองค์ประกอบที่มีทีละองค์ประกอบ ทุกครั้งที่มีการเรียกเมธอดนั้น โดยแสดงผลออบเจ็กต์สำหรับแต่ละลำดับ องค์ประกอบในรูปแบบที่กำหนด

โครงสร้างข้อมูลแบบวนซ้ำได้ในตัวของ JavaScript (เช่น อาร์เรย์ แผนที่ และ ตั้งค่า) ไม่ใช่ตัวทำซ้ำในและของ แต่ทั้งหมดมีการสืบทอดเมธอด iterator ซึ่งสามารถเข้าถึงได้โดยใช้ @@iterator สัญลักษณ์ที่รู้จักกันดี ซึ่งจะแสดงผลออบเจ็กต์ Iterator ที่สร้างจากโครงสร้างข้อมูลแบบทำซ้ำได้

const myIterable = [ 1, 2, 3 ];
const myIterator = myIterable[ Symbol.iterator ]();

myIterable
;
> (3) [1, 2, 3]

myIterator
;
> Array Iterator {}

การเรียกเมธอด next() ในอิเทอเรเตอร์จะทำขั้นตอนผ่านองค์ประกอบ ครั้งละ 1 รายการ โดยการเรียกแต่ละครั้งจะแสดงออบเจ็กต์ที่มี พร็อพเพอร์ตี้: value ซึ่งมีค่าขององค์ประกอบปัจจุบัน และ done ซึ่งเป็นบูลีนที่บอกเราหากตัววนซ้ำผ่านองค์ประกอบสุดท้ายใน โครงสร้างข้อมูล ค่าของ done คือ true เฉพาะเมื่อโทรหา next() ทำให้พยายามเข้าถึงองค์ประกอบอื่นนอกเหนือจากองค์ประกอบสุดท้ายใน ตัวซ้ำ

const myIterable = [ 1, 2, 3 ];
const myIterator = myIterable[ Symbol.iterator ]();

myIterator
.next();
> Object { value: 1, done: false }

myIterator
.next();
> Object { value: 2, done: false }

myIterator
.next();
> Object { value: 3, done: false }

myIterator
.next();
> Object { value: undefined, done: true }

ฟังก์ชันของโปรแกรมสร้าง

ใช้คีย์เวิร์ด function* (สังเกตเครื่องหมายดอกจัน) เพื่อประกาศเครื่องมือสร้าง ฟังก์ชันหรือกำหนดนิพจน์ฟังก์ชันของโปรแกรมสร้าง:

function* myGeneratorFunction() { };

ฟังก์ชันของโปรแกรมสร้างจะรักษาสถานะไว้เช่นเดียวกับ iterator กำลังโทรหา ฟังก์ชันของโปรแกรมสร้างแสดงออบเจ็กต์โปรแกรมสร้างใหม่ แต่ไม่แสดงผลทันที เรียกใช้โค้ดในส่วนเนื้อหาของฟังก์ชัน

function* myGeneratorFunction() {
  console
.log( "Generator function body ")
};
const myGeneratorObject = myGeneratorFunction();

myGeneratorObject
;
> Generator {  }

typeof myGeneratorObject;
> "object"

ออบเจ็กต์ของเครื่องมือสร้างเป็นไปตามโปรโตคอลของ Iterator มูลค่าที่ได้จากการเรียกแต่ละรายการ next() ในฟังก์ชันของโปรแกรมสร้างการค้นหาจะกำหนดโดยนิพจน์ yield ซึ่งจะหยุดการดำเนินการของฟังก์ชันตัวสร้างชั่วคราว และแสดงผลค่าของฟังก์ชัน นิพจน์ที่มีคีย์เวิร์ด yield คำ โทรหา next() ในภายหลัง ดำเนินการของฟังก์ชันต่อ โดยหยุดชั่วคราวที่นิพจน์ yield ถัดไปและ ซึ่งแสดงผลค่าที่เกี่ยวข้อง

function* myGeneratorFunction() {
 
yield "My first yielded value.";
 
yield "My second yielded value.";
};
const myGeneratorObject = myGeneratorFunction();

myGeneratorObject
.next();
> Object { value: "My first yielded value.", done: false }

myGeneratorObject
.next();
> Object { value: "My second yielded value.", done: false }

เมื่อมีการเรียก next() หลังจากไม่ได้ระบุค่าเพิ่มเติมโดยใช้ yield return หรือ throw (ในกรณีที่เกิดข้อผิดพลาด) ส่วนที่เหลือของฟังก์ชัน ร่างกายประมวลผล และออบเจ็กต์ที่แสดงผลมี value เป็น undefined และ done พร็อพเพอร์ตี้ของ true:


function* myGeneratorFunction() {
    console
.log( "Start of the generator function." );
   
yield "First";
    console
.log( "Second part of the generator function."  );
   
yield "Second";
    console
.log( "Third part of the generator function." );
   
yield "Third";
};
const myGeneratorObject = myGeneratorFunction();

myGeneratorObject
.next();
> "Start of the generator function."
> Object { value: "First", done: false }

myGeneratorObject
.next();
> "Second part of the generator function."
> Object { value: "Second", done: false }

myGeneratorObject
.next();
> "Third part of the generator function."
> Object { value: "Third", done: false }

myGeneratorObject
.next();
> Object { value: undefined, done: true }

ใช้ next() เฉพาะกับออบเจ็กต์ที่ฟังก์ชันโปรแกรมสร้างจะแสดงผล ไม่ใช่ ของตัวสร้างก็ใช้งานได้เอง ไม่เช่นนั้น การเรียกฟังก์ชันการสร้างแต่ละครั้ง สร้างออบเจ็กต์ตัวสร้างใหม่ดังนี้

function* myGeneratorFunction() {
 
yield "First";
 
yield "Second";
};

myGeneratorFunction
().next();
> Object { value: "First", done: false }

myGeneratorFunction
().next();
> Object { value: "First", done: false }

เช่นเดียวกับฟังก์ชันอื่นๆ ฟังก์ชันของโปรแกรมสร้างจะหยุดทำงานเมื่อเจอ return คีย์เวิร์ด จากนั้นจะส่งออบเจ็กต์กลับไปยังบริบทการเรียกใช้ที่มีฟังก์ชัน แสดงผลค่าและพร็อพเพอร์ตี้ done ที่มีค่า true

function* myGeneratorFunction() {
 
yield 1;
 
yield 2;
 
return 3;
};
const myGeneratorObject = myGeneratorFunction();

myGeneratorObject
.next().done;
> Object { value: 1, done: false }

myGeneratorObject
.next().done;
> Object { value: 2, done: false }

myGeneratorObject
.next();
> Object { value: 3, done: true }

นิพจน์ yield รับความหมายบางอย่างของตัวระบุได้ อนุญาต "การสื่อสาร" แบบ 2 ทาง จากและกลับไปยังส่วนที่ถูกระงับของ ของโปรแกรมสร้าง เมื่อมีการส่งค่าไปยังเมธอด next() ของโปรแกรมสร้างในรูปแบบ อาร์กิวเมนต์ อาร์กิวเมนต์จะแทนที่ค่าที่เชื่อมโยงกับรายการก่อนหน้าที่ถูกระงับ นิพจน์ yield:

function* myGeneratorFunction() {
   
const firstYield = yield;
   
yield firstYield + 10;
};
const myGeneratorObject = myGeneratorFunction();

myGeneratorObject
.next();
> Object { value: undefined, done: false }

myGeneratorObject
.next( 5 );
> Object { value: 15, done: false }

โปรดทราบว่าพารามิเตอร์นี้จะแทนที่นิพจน์ทั้งหมดที่เชื่อมโยงกับ yield ก่อนหน้า และไม่ได้กำหนดมูลค่าของ yield ก่อนหน้าใหม่ให้กับ ค่าที่ระบุใน next():

function* myGeneratorFunction() {
   
const firstYield = yield;
   
const secondYield = yield firstYield + 100;
   
yield secondYield + 10;
};
const myGeneratorObject = myGeneratorFunction();

myGeneratorObject
.next();
> Object { value: undefined, done: false }

myGeneratorObject
.next( 10 ); // Can be thought of as changing the value of the `firstYield` variable to `10
> Object { value: 110, done: false }

myGeneratorObject
.next( 20 ); // Can be thought of as changing the value of the `secondYield` variable to `20`, _not_ `20 + 100;`
> Object { value: 30, done: false }

อาร์กิวเมนต์ใดๆ ที่ส่งไปยังการเรียก next() ครั้งแรกจะถูกละเว้น เนื่องจากไม่มี นิพจน์ yield ก่อนหน้าเพื่อยอมรับค่านั้น เช่นเดียวกับฟังก์ชันอื่นๆ อาร์กิวเมนต์ที่ส่งผ่านไปยังการเรียกใช้ฟังก์ชันของโปรแกรมสร้างเริ่มต้นพร้อมใช้งานตลอด ขอบเขตของส่วนเนื้อหาของฟังก์ชันเครื่องสร้าง:

function* myGeneratorFunction( startingValue ) {
    let newValue
= yield startingValue + 1;
    newValue
= yield newValue + 10;
   
yield startingValue + 20;
};
const myGeneratorObject = myGeneratorFunction( 2 );

myGeneratorObject
.next( 1 );
> Object { value: 3, done: false }

myGeneratorObject
.next( 5 );
> Object { value: 15, done: false }

myGeneratorObject
.next( 10 );
Object { value: 22, done: false }

โอเปอเรเตอร์ yield* (โปรดสังเกตเครื่องหมายดอกจัน) ใช้กับโอเปอเรเตอร์ซ้ำได้ เช่น ฟังก์ชันตัวสร้างอื่นเพื่อทำซ้ำและแสดงผลแต่ละค่าตัวถูกดำเนินการ การคืนสินค้า:

function* mySecondaryGenerator() {
 
yield 2;
 
yield 3;
}

function* myGenerator() {
 
yield 1;
 
yield* mySecondaryGenerator();
 
yield 4;
 
return 5;
}

const myIterator = myGenerator();

myIterator
.next();
> Object { value: 1, done: false }

myIterator
.next();
> Object { value: 2, done: false }

myIterator
.next();
> Object { value: 3, done: false }

myIterator
.next();
> Object { value: 4, done: false }

myIterator
.next();
> Object { value: 5, done: true }

JavaScript แบบอะซิงโครนัส

แม้ว่าโดยพื้นฐานแล้ว JavaScript จะเป็นซิงโครนัส ในการดำเนินการยังมีกลไกที่ทำให้นักพัฒนาซอฟต์แวร์สามารถนำ Event Loop ในการดำเนินการ งานที่ไม่พร้อมกัน

คำมั่นสัญญา

Promise คือตัวยึดตำแหน่งสำหรับค่าที่ไม่รู้จักเมื่อสัญญาคือ สร้าง แล้ว เป็นคอนเทนเนอร์ที่กำหนดการดำเนินการแบบไม่พร้อมกัน การดำเนินการที่ถือว่าสำเร็จหรือล้มเหลว การดำเนินการที่ทำได้ ไม่ว่าในกรณีใด และมูลค่าที่ได้

สร้างอินสแตนซ์ Promise โดยใช้โอเปอเรเตอร์ new ที่มี Promise ในตัว ของตัวสร้าง ตัวสร้างนี้ยอมรับฟังก์ชันที่เรียกว่าผู้ดำเนินการ เป็นอาร์กิวเมนต์ โดยทั่วไปฟังก์ชันผู้ดำเนินการดังกล่าวจะใช้เพื่อดำเนินการอย่างน้อย 1 รายการ แบบไม่พร้อมกัน แล้วพิมพ์คำที่จะให้คำมั่นสัญญา ถือว่าสำเร็จหรือปฏิเสธแล้ว Promise แปลว่ารอดำเนินการ ขณะที่ฟังก์ชันผู้ดำเนินการกำลังทำงาน หลังจากที่ผู้ดำเนินการเสร็จสิ้น สัญญา จะถือว่าดำเนินการแล้ว (หรือแก้ไขแล้วในแหล่งที่มาของเอกสารประกอบบางแหล่ง) หาก ฟังก์ชันผู้ดำเนินการและการดำเนินการแบบอะซิงโครนัสที่ดำเนินอยู่จะเสร็จสมบูรณ์ สำเร็จ และปฏิเสธหากฟังก์ชันผู้ดำเนินการพบข้อผิดพลาด หรือ การทำงานแบบอะซิงโครนัสที่ดำเนินการอยู่ล้มเหลว หลังจากทำตามคำสัญญาแล้ว หรือ ถูกปฏิเสธ ก็จะถือว่าตกลงกันแล้ว

const myPromise = new Promise( () => { });

ตัวสร้างเรียกใช้ฟังก์ชันผู้ดำเนินการโดยมีอาร์กิวเมนต์ 2 ตัว อาร์กิวเมนต์เหล่านั้น เป็นฟังก์ชันที่ช่วยให้คุณทำตามคำสัญญาหรือปฏิเสธคำสัญญาด้วยตนเอง ดังนี้

const  myPromise = new Promise( ( fulfill, reject ) => { });

ฟังก์ชันที่ใช้ในการทำหรือปฏิเสธคำสัญญาจะถูกเรียกใช้พร้อมกับผลลัพธ์ ค่าของ Promise เป็นอาร์กิวเมนต์ (โดยทั่วไปจะเป็นข้อผิดพลาดสำหรับการปฏิเสธ):

const myPromise = new Promise( ( fulfill, reject ) => {
 
const myResult = true;
  setTimeout
(() => {
   
if( myResult === true ) {
        fulfill
( "This Promise was successful." );    
   
} else {
        reject
( new Error( "This Promise has been rejected." ) );
   
}
 
}, 10000);
});

myPromise
;
> Promise { <state>: "pending" }

myPromise
;
> Promise { <state>: "fulfilled", <value>: "This Promise was successful." }

แบบต่อสัญญา (Promise Chaining)

ออบเจ็กต์ Promise ที่ได้จะทำงานโดยใช้ then(), catch() และ finally() เมธอดได้รับช่วงมาจากตัวสร้าง Promise แต่ละรายการ จะแสดงผลเป็น "คำสัญญา" ซึ่งสามารถดำเนินการด้วย then() ได้ทันที catch() หรือ finally() อีกครั้ง แล้วให้คุณเชื่อมโยง Promises ที่ได้

then() มีฟังก์ชัน Callback 2 ฟังก์ชันเป็นอาร์กิวเมนต์ ใช้รายการแรกเพื่อดำเนินการตามคำสั่งซื้อ "คำสัญญา" ผลลัพธ์ และคำที่สองที่จะปฏิเสธ ทั้ง 2 วิธีจะยอมรับ ซึ่งจะให้ค่าของ Promise ที่ได้

const myPromise = new Promise( ( fulfill, reject ) => {
 
const myResult = true;
  setTimeout
(() => {
   
if( myResult === true ) {
        fulfill
( "This Promise was fulfilled." );    
   
} else {
        reject
( new Error( "This Promise has been rejected." ) );
   
}
 
}, 100);
});

myPromise
.then( successfulResult => console.log( successfulResult ), failedResult => console.error( failedResult ) );
> "This Promise was successful."

นอกจากนี้ คุณยังใช้ then() เพื่อจัดการเฉพาะสถานะ "ดำเนินการแล้ว" และใช้ catch เพื่อ จัดการกับสถานะที่ถูกปฏิเสธ เรียก catch ด้วยอาร์กิวเมนต์เดียวที่มีพารามิเตอร์ ค่าที่ระบุในวิธีการปฏิเสธของ Promise:

const myPromise = new Promise( ( fulfill, reject ) => {
 
const myResult = false;
  setTimeout
(() => {
   
if( myResult === true ) {
        fulfill
( "This Promise was fulfilled." );    
   
} else {
        reject
( new Error( "This Promise has been rejected." ) );
   
}
 
}, 100);
});

myPromise
 
.then( fulfilledResult => console.log(fulfilledResult ) )
 
.catch( rejectedResult => console.log( rejectedResult ) )
 
.finally( () => console.log( "The Promise has settled." ) );
> "Error: This Promise has been rejected."
> "The Promise has settled."

ต่างจาก then และ catch ที่ทำให้ฟังก์ชันตัวแฮนเดิลทำงานเมื่อ "Promise" ได้รับการตอบสนองหรือปฏิเสธ ฟังก์ชันที่ส่งผ่านเป็นอาร์กิวเมนต์ไปยัง finally โดยไม่คำนึงว่าคำสัญญาจะได้รับการดำเนินการหรือปฏิเสธ ฟังก์ชันตัวแฮนเดิลจะถูกเรียกโดยไม่มีอาร์กิวเมนต์ เนื่องจากฟังก์ชันดังกล่าวไม่ได้มีไว้เพื่อ ทำงานกับค่าที่ส่งผ่านจาก Promise เพื่อเรียกใช้โค้ดหลังจาก Promise เสร็จสมบูรณ์

การเกิดขึ้นพร้อมกัน

เครื่องมือสร้าง Promise นำเสนอ 4 วิธีสำหรับการทำงานกับหลายรายการ Promise โดยใช้ iterable ที่มีออบเจ็กต์ Promise เหล่านี้ แต่ละวิธีจะแสดงผลคำสัญญา ซึ่งจะมีการดำเนินการหรือปฏิเสธตามรัฐ ของผู้ทรงคำมั่นสัญญาที่ให้ไว้ ตัวอย่างเช่น Promise.all() สร้าง "คำสัญญา" จะมีการดำเนินการก็ต่อเมื่อ "คำสัญญา" ทุกรายการที่ส่งไปยังวิธีการนั้นได้รับการบรรลุผล

const firstPromise  = new Promise( ( fulfill, reject ) => fulfill( "Successful. ") );
const secondPromise = new Promise( ( fulfill, reject ) => fulfill( "Successful. ") );
const thirdPromise  = new Promise( ( fulfill, reject ) => fulfill( "Successful. ") );
const failedPromise = new Promise( ( fulfill, reject ) => reject( "Failed.") );
const successfulPromises = [ firstPromise, secondPromise, thirdPromise ];
const oneFailedPromise = [ failedPromise, ...successfulPromises ];

Promise.all( successfulPromises )
 
.then( ( allValues ) => {
    console
.log( allValues );
 
})
 
.catch( ( failValue ) => {
    console
.error( failValue );
 
});
> Array(3) [ "Successful. ", "Successful. ", "Successful. " ]

Promise.all( oneFailedPromise  )
   
.then( ( allValues ) => {
      console
.log( allValues );
   
})
   
.catch( ( failValue ) => {
     console
.error( failValue );
   
});
> "Failed."

วิธีการของการเกิดขึ้นพร้อมกันของ Promise มีดังนี้

Promise.all()
จะมีการดำเนินการก็ต่อเมื่อคำสัญญาที่ให้ไว้ทั้งหมดเท่านั้น
Promise.any()
มีการดำเนินการตามคำสัญญารายการใดรายการหนึ่งที่ระบุสำเร็จ และถูกปฏิเสธเท่านั้น หากคำสัญญาทั้งหมดถูกปฏิเสธ
Promise.allSettled()
ดำเนินการตามคำสั่งซื้อเมื่อ Promises ตัดสินแล้ว ไม่ว่าผลลัพธ์จะเป็นอย่างไร
Promise.race()
ถูกปฏิเสธหรือดำเนินการตามข้อเสนอจากสัญญาว่าจะปิดยอดครั้งแรก เพิกเฉยต่อคำสัญญาทั้งหมดซึ่งตกลงกันภายหลัง

async/await

เมื่อคุณใช้คีย์เวิร์ด async ก่อนการประกาศฟังก์ชัน หรือนิพจน์ฟังก์ชัน ค่าที่ฟังก์ชันแสดงผลจะถูกส่งคืนเป็น Promise ที่ตอบสนองแล้วซึ่งมีค่านั้น ซึ่งจะช่วยให้คุณเรียกใช้และจัดการการดำเนินการแบบไม่พร้อมกันโดยใช้ แบบไม่พร้อมกัน

async function myFunction() {
 
return "This is my returned value.";
}

myFunction
().then( myReturnedValue => console.log( myReturnedValue ) );
> "This is my returned value."

นิพจน์ await จะหยุดการดำเนินการของฟังก์ชันอะซิงโครนัสชั่วคราวในขณะที่ คำสัญญาที่เกี่ยวข้องได้รับการชำระแล้ว หลังจากปิดยอด Promise แล้ว ค่าของ นิพจน์ await คือค่า "สัญญา" ที่ได้รับหรือถูกปฏิเสธ

async function myFunction() {
 
const myPromise  = new Promise( ( fulfill, reject ) => { setTimeout( () => fulfill( "Successful. "), 5000 ); });
 
const myPromisedResult = await myPromise;
 
return myPromisedResult;
}

myFunction
()
 
.then( myResult => console.log( myResult ) )
 
.catch( myFailedResult => console.error( myFailedResult ) );
> "Successful."

ค่าที่ไม่ใช่ Promise ใดๆ ที่รวมอยู่ในนิพจน์ await จะแสดงผลเป็น คำมั่นสัญญาที่ทำสำเร็จ:

async function myFunction() {
 
const myPromisedResult = await "String value.";
 
return myPromisedResult;
}

myFunction
()
 
.then( myResult => console.log( myResult ) )
 
.catch( myFailedResult => console.error( myFailedResult ) );
> "String value."

ตรวจสอบความเข้าใจ

ลูปประเภทใดที่คุณใช้เพื่อทำซ้ำตามจำนวนที่ทราบ

while
do...while
for