โฟลว์การควบคุมคือลำดับที่ล่าม JavaScript เรียกใช้ ข้อความ หากสคริปต์ไม่รวมคำสั่งที่เปลี่ยนขั้นตอน ดำเนินการตั้งแต่ต้นจนจบ ทีละบรรทัด โครงสร้างการควบคุม ใช้ในการพิจารณาว่าชุดคำสั่งจะได้รับการดำเนินการโดยอิงตาม ชุดของเกณฑ์ที่กำหนดไว้ ดำเนินการตามชุดคำสั่งซ้ำๆ หรือขัดจังหวะ ลำดับของข้อความ
คำสั่งแบบมีเงื่อนไข
คำสั่งแบบมีเงื่อนไขจะกำหนดว่าควรเรียกใช้โค้ดจากโค้ด
เงื่อนไขเพิ่มเติม คำสั่งแบบมีเงื่อนไขจะเรียกใช้โค้ดที่อยู่ในโค้ดหาก
เงื่อนไขที่เกี่ยวข้อง (หรือชุดเงื่อนไข) จะประเมินเป็น true
มิเช่นนั้น แอตทริบิวต์
ข้ามรหัส
if
…else
คำสั่ง 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."
switch
…case
ใช้คำสั่ง 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."
do
…while
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 รายการต่อไปนี้ตามลำดับและคั่นด้วย
เครื่องหมายเซมิโคลอน:
- นิพจน์ที่จะประเมินเมื่อเริ่มวนซ้ำ
- เงื่อนไขที่กําหนดว่าควรวนซ้ำต่อหรือไม่
- นิพจน์ที่จะดำเนินการเมื่อสิ้นสุดแต่ละลูป
หลังวงเล็บเหล่านี้ ให้เพิ่มคำสั่ง (โดยทั่วไปคือ คำสั่งบล็อก) เป็น เรียกใช้ในระหว่างการวนซ้ำ
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
จะกำหนดขอบเขตเฉพาะคำสั่งบล็อกภายใน
วนซ้ำ ระบบจะเริ่มต้นตัวแปรเมื่อเริ่มต้นการทำซ้ำแต่ละครั้ง และนําออกที่
เมื่อสิ้นสุดการทำซ้ำๆ
for
in
...
ใช้การวนซ้ำ 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."
ตรวจสอบความเข้าใจ
ลูปประเภทใดที่คุณใช้เพื่อทำซ้ำตามจำนวนที่ทราบ
for
while
do...while