ๆญค้ ้ข็”ฑ็คพ็พคๅพž่‹ฑๆ–‡็ฟป่ญฏ่€Œไพ†ใ€‚ไบ†่งฃๆ›ดๅคšไธฆๅŠ ๅ…ฅ MDN Web Docs ็คพ็พคใ€‚

View in English Always switch to English

ไธฆ่กŒๆจกๅž‹ๅ’Œไบ‹ไปถๅพช็’ฐ

JavaScript ็š„ไธฆ่กŒๆจกๅž‹๏ผˆconcurrency model๏ผ‰ๆ˜ฏๅŸบๆ–ผใ€Œไบ‹ไปถๅพช็’ฐ๏ผˆevent loop๏ผ‰ใ€๏ผŒๅ…ถๅœจ้‹ไฝœไธŠ่ทŸ C ๆˆ–ๆ˜ฏ Java ๆœ‰ๅพˆๅคง็š„ไธๅŒใ€‚

ๅŸท่กŒ็’ฐๅขƒๆฆ‚ๅฟต๏ผˆRuntime concepts๏ผ‰

ไธ‹้ข็š„ๅ…งๅฎน่งฃ้‡‹ไบ†ไธ€ๅ€‹็†่ซ–ๆจกๅž‹๏ผŒ็พไปฃ JavaScript ๅผ•ๆ“Žๅฏฆไฝœไบ†ๅŠๅพˆๅคง็จ‹ๅบฆๅœฐๆœ€ไฝณๅŒ–ไบ†่ฉฒๅœ–ๆ‰€ๆ่ฟฐ็š„่ชžๆ„ใ€‚

่ฆ–่ฆบๅŒ–ๅ‘ˆ็พ๏ผˆVisual representation๏ผ‰

Stack, heap, queue

ๅ †็–Š๏ผˆStack๏ผ‰

ๅ‘ผๅซๅ‡ฝๅผ๏ผˆFunction๏ผ‰ๆœƒๅฝขๆˆไธ€ๅ€‹ frame ็š„ๅ †็–Šใ€‚

js
function foo(b) {
  var a = 10;
  return a + b + 11;
}

function bar(x) {
  var y = 3;
  return foo(x * y);
}

console.log(bar(7));

็•ถๅ‘ผๅซ bar ๆ™‚๏ผŒๆœƒ็”ข็”Ÿไธ€ๅ€‹ๅซๆœ‰ bar ็š„ๅƒๆ•ธๅŠๅ€ๅŸŸ่ฎŠๆ•ธ็š„ frame๏ผŒ่€Œๅœจ bar ๅ‘ผๅซไบ† foo ๆ™‚๏ผŒๅซๆœ‰ foo ๅƒๆ•ธๅŠ่ฎŠๆ•ธ็š„็ฌฌไบŒๅ€‹ frame ๅฐฑๆœƒ่ขซ็ฝฎๆ–ผๅ †็–Š็š„ๆœ€ไธŠ้ขใ€‚็•ถ foo ๅ›žๅ‚ณๅพŒ๏ผŒๆœ€ไธŠ้ข็š„ frame ๆœƒ่ขซๆŠฝ้›ขๅ †็–Š๏ผˆๅƒ…็•™ไธ‹ bar ็š„ๅ‘ผๅซ frame๏ผ‰ใ€‚็„ถๅพŒ็•ถ bar ่ฟ”ๅ›žไน‹ๅพŒ๏ผŒๅ †็–Šๅฐฑๆœƒๆธ…็ฉบใ€‚

ๅ †็ฉ๏ผˆHeap๏ผ‰

็‰ฉไปถ่ขซๅˆ†้…ๅœจไธ€ๅ€‹ๅ †็ฉไธญ๏ผŒไธ€ๅ€‹ๅช่กจ็คบ่จ˜ๆ†ถ้ซ”ไธญ็š„ไธ€ๅ€‹็„ก็ตๆง‹็š„ๅคงๅ€ๅŸŸใ€‚

ไฝ‡ๅˆ—๏ผˆQueue๏ผ‰

JavaScript ๅŸท่กŒ็’ฐๅขƒๅŒ…ๅซไธ€ๅ€‹่จŠๆฏไฝ‡ๅˆ—๏ผŒ่ฃก้ขๆ˜ฏๅพ…่™•็†็š„่จŠๆฏ๏ผŒๅ…ถไธญๆฏๅ€‹่จŠๆฏ้ƒฝ่ˆ‡ไธ€ๅ€‹ function ็›ธ้—œ่ฏใ€‚็•ถๅ †็–Šไธญๆœ‰่ถณๅค ็ฉบ้–“ๆ™‚๏ผŒๆœƒๅพž่จŠๆฏไฝ‡ๅˆ—ๆ‹ฟๅ–ไธ€ๅ€‹่จŠๆฏ้€ฒ่กŒ่™•็†๏ผŒ่™•็†้Ž็จ‹ๅŒ…ๅซไบ†ๅ‘ผๅซ็›ธ้—œ่ฏ็š„ functionใ€‚ๅชๆœ‰็•ถๅ †็–Šๆธ…็ฉบๆ™‚๏ผŒ่ฉฒ่จŠๆฏๆ‰็ฎ—ๆ˜ฏๅฎŒๆˆ่™•็†ใ€‚

ไบ‹ไปถๅพช็’ฐ๏ผˆEvent loop๏ผ‰

ไน‹ๆ‰€ไปฅ่ขซ็จฑ็‚บไบ‹ไปถๅพช็’ฐ๏ผŒๆ˜ฏๅ› ็‚บ็ถ“ๅธธ่ขซไปฅๅฆ‚ไธ‹็š„ๆ–นๅผๅฏฆไฝœ๏ผš

js
while (queue.waitForMessage()) {
  queue.processNextMessage();
}

็•ถๆฒ’ๆœ‰ไปปไฝ•่จŠๆฏๆ™‚๏ผŒqueue.waitForMessage ๆœƒๅŒๆญฅๅœฐ็ญ‰ๅพ…ๆ–ฐ่จŠๆฏๅˆฐไพ†ใ€‚

ๅŸท่กŒๅˆฐๅฎŒๆˆ๏ผˆRun-to-completion๏ผ‰

ๆฏไธ€ๅ€‹่จŠๆฏ่™•็†ๅฎŒๆˆไน‹ๅพŒๆ‰ๆœƒๅŸท่กŒไธ‹ไธ€ๅ€‹ใ€‚็•ถๅˆ†ๆžไฝ ็š„็จ‹ๅผ็š„ๆ™‚ๅ€™๏ผŒไธŠ่ฟฐๆไพ›ไบ†ๅ„ช็ง€็š„็‰นๆ€ง๏ผŒๅƒๆ˜ฏ็•ถไธ€ๅ€‹ๅ‡ฝๅผ้–‹ๅง‹ๅŸท่กŒๆ™‚๏ผŒไป–ไธๆœƒ่ขซๅ–ไปฃไธ”ๅ…ถไป–็จ‹ๅผ็ขผๅŸท่กŒๅ‰ๅ…ˆๅฎŒๆˆ๏ผˆ่€Œไธ”ๅฏไปฅไฟฎๆ”น้€™ๅ€‹ๅ‡ฝๅผๆ“ไฝœ็š„่ณ‡ๆ–™๏ผ‰ใ€‚้€™็‰นๆ€ง่ˆ‡ C ไธๅŒ๏ผŒๅœจ C ็•ถไธญ๏ผŒ็•ถไธ€ๅ€‹ๅ‡ฝๅผๅœจๅŸท่กŒ็ท’ไธญๅŸท่กŒๆ™‚๏ผŒ้šจๆ™‚ๅฏไปฅ่ขซๅ…ถไป–ๅŸท่กŒ็ท’ไธญ็š„็จ‹ๅผ็ขผไธญๆญขใ€‚

้€™ๆจกๅž‹็š„็ผบ้ปžๆ˜ฏ๏ผš่‹ฅๆ˜ฏไธ€ๅ€‹่จŠๆฏ่ฆๅŸท่กŒๅพˆไน…ๆ‰ๅฎŒๆˆ๏ผŒ็ถฒ้ ๆ‡‰็”จ็จ‹ๅผๆœƒ็„กๆณ•ๅŸท่กŒไธ€ไบ›ไฝฟ็”จ่€…็š„ๅŸบๆœฌๆ“ไฝœ๏ผŒๅฆ‚้ปžๆ“ŠๆŒ‰้ˆ•ๆˆ–ๆ˜ฏๆฒๅ‹•้ ้ขใ€‚็€่ฆฝๅ™จ็‚บไบ†่ฆ็ทฉ่งฃ้€™ๅ•้กŒ๏ผŒๆœƒ่ทณๅ‡บ่ฆ–็ช—ใ€Œ่ฉฒๅ‹•ไฝœๅ›žๆ‡‰ๆ™‚้–“้Žไน…๏ผˆa script taking too long to run๏ผ‰ใ€ใ€‚่‰ฏๅฅฝ็š„ๅฏฆไฝœๆ–นๅผๆ˜ฏ็ธฎ็ŸญๅŸท่กŒ่จŠๆฏ๏ผŒ่‹ฅๅฏ่ƒฝ็š„่ฉฑ๏ผŒๅฐ‡ไธ€ๅ€‹่จŠๆฏๅˆ‡ๆˆๆ•ธๅ€‹่จŠๆฏๅŸท่กŒใ€‚

ๆทปๅŠ ่จŠๆฏ๏ผˆAdding message๏ผ‰

็€่ฆฝๅ™จไธญ๏ผŒๆœƒๆทปๅŠ ่จŠๆฏๆ˜ฏ็”ฑๆ–ผไบ‹ไปถ็š„่งธๅ‹•๏ผŒไปฅๅŠไผด้šจ่‘—ไบ‹ไปถ็š„็›ฃ่ฝ่€…ใ€‚่‹ฅๆ˜ฏๆฒ’ๆœ‰ไบ‹ไปถ็›ฃ่ฝ่€…๏ผŒๅ‰‡่ฉฒไบ‹ไปถ็š„่งธๅ‹•ๅฐฑไธๆœƒๅฝขๆˆ่จŠๆฏ๏ผŒไพ‹ๅฆ‚่ชชไธ€ๅ€‹้ปžๆ“Š็š„ๅ‹•ไฝœไผด้šจ่‘—้ปžๆ“Šไบ‹ไปถ็›ฃ่ฝ่€…ๅฐฑๆœƒๅฝขๆˆไธ€ๅ€‹ๆ–ฐ็š„่จŠๆฏ๏ผŒๅ…ถไป–้กžไบ‹ไปถไบฆ็„ถใ€‚

ๅ‘ผๅซ setTimeout ๆ™‚ๆœ‰ๅ…ฉๅ€‹ๅƒๆ•ธ๏ผš็ฌฌไธ€ๅ€‹ๆ˜ฏๆœƒ่ขซๅŠ ๅ…ฅๅˆฐไฝ‡ๅˆ—ไธญ็š„่จŠๆฏ๏ผŒ็ฌฌไบŒๅ€‹ๅƒๆ•ธ็‚บๅปถ้ฒๆ™‚้–“๏ผˆ้ ่จญ็‚บ0๏ผ‰ใ€‚่‹ฅ็„กๅ…ถไป–่จŠๆฏๅœจไฝ‡ๅˆ—ไธญ๏ผŒๅ‰‡้€™ๅ€‹่จŠๆฏๆœƒๅœจ่จญๅฎš็š„ๅปถ้ฒๅพŒ็ซ‹ๅˆป่ขซ่™•็†ใ€‚ไฝ†่‹ฅไฝ‡ๅˆ—ๅ…งๆœ‰ๅ…ถไป–่จŠๆฏ๏ผŒsetTimeout ็š„่จŠๆฏๅฟ…้ ˆ็ญ‰ๅˆฐๅ…ถไป–่จŠๆฏ่™•็†ๅฎŒใ€‚ๅ› ๆญค็ฌฌไบŒๅ€‹ๆ™‚้–“ๅƒๆ•ธๅช่ƒฝ่กจ็คบ็‚บๆœ€ๅฐ‘ๆ™‚้–“๏ผŒ่€Œไธๆ˜ฏไธ€ๅ€‹็ฒพๆบ–็š„ๆ™‚้–“ใ€‚

้€™่ฃกๆœ‰ๅ€‹็คบ็ฏ„ๆญคๆฆ‚ๅฟต็š„ไพ‹ๅญ๏ผˆsetTimeoutๅœจๅ…ถ่จˆๆ™‚ๅ™จๅˆฐๆœŸๅพŒไธๆœƒ็ซ‹ๅˆปๅŸท่กŒ๏ผ‰๏ผš

js
const s = new Date().getSeconds();

setTimeout(function () {
  // prints out "2", meaning that the callback is not called immediately after 500 milliseconds.
  console.log("Ran after " + (new Date().getSeconds() - s) + " seconds");
}, 500);

while (true) {
  if (new Date().getSeconds() - s >= 2) {
    console.log("Good, looped for 2 seconds");
    break;
  }
}

้›ถๅปถ้ฒ๏ผˆZero delay๏ผ‰

ใ€Œ้›ถๅปถ้ฒใ€ไธฆ้žๆ„ๅ‘ณ่‘—ๅ›žๅ‘ผๅ‡ฝๅผ๏ผˆcallback function๏ผ‰ๆœƒๅœจ 0 ๆฏซ็ง’ไน‹ๅพŒ็ซ‹ๅˆปๅŸท่กŒใ€‚็•ถไฝฟ็”จๅปถ้ฒ 0 ๆฏซ็ง’ๅƒๆ•ธไพ†ๅ‘ผๅซ setTimeout ๅ‡ฝๅผไธฆ้žๆ˜ฏ็จ‹ๅผๆœƒ้Žไบ†่ฉฒๆฎตๆ™‚้–“ๅฐฑๆœƒๅŸท่กŒ๏ผŒ่€Œๆ˜ฏๆœƒๅƒ่€ƒไฝ‡ๅˆ—ไธญ็ญ‰ๅพ…็š„่จŠๆฏๆ•ธ้‡ใ€‚ ๅœจไธ‹้ข็ฏ„ไพ‹ไธญ๏ผŒใ€Œthis is just a messageใ€ๆœƒๅฏซๅœจ setTimeout ็š„ๅ›žๅ‘ผ่จŠๆฏ่ขซๅŸท่กŒไน‹ๅ‰๏ผŒๅ› ็‚บ่ฉฒๆ™‚้–“ๆฎตๅƒๆ•ธๆ˜ฏ่ฆๆฑ‚ๅŸท่กŒ็’ฐๅขƒ่™•็†ๆ‰€้œ€็š„ๆœ€ๅฐ‘็ญ‰ๅพ…ๆ™‚้–“๏ผŒ่€Œ้žไธ€ๅ€‹ไฟ่ญ‰ๆ™‚้–“ใ€‚

js
(function () {
  console.log("this is the start");

  setTimeout(function cb() {
    console.log("this is a msg from call back");
  });

  console.log("this is just a message");

  setTimeout(function cb1() {
    console.log("this is a msg from call back1");
  }, 0);

  console.log("this is the end");
})();

// "this is the start"
// "this is just a message"
// "this is the end"
// "this is a msg from call back"
// "this is a msg from call back1"

ๅคšๅ€‹ๅŸท่กŒ็’ฐๅขƒ็š„ไบ’็›ธๆบ้€š๏ผˆSeveral Runtime communicating together๏ผ‰

Web worker ๆˆ–ๆ˜ฏ่ทจไพ†ๆบ็ถฒๅŸŸ๏ผˆcross-origin๏ผ‰็š„ iframe ้ƒฝๆœƒๆœ‰ๅ„่‡ช็š„ๅ †็–Šใ€ๅ †็ฉๅŠ่จŠๆฏไฝ‡ๅˆ—ใ€‚ๅ…ฉๅ€‹็‰นๅฎš็š„ๅŸท่กŒ็’ฐๅขƒๅช่ƒฝ้€้Ž postMessage ้€™ๅ€‹ๆ–นๆณ•ไพ†ๆบ้€šใ€‚ๅฆ‚ๆžœไธ€ๅ€‹ๅŸท่กŒ็’ฐๅขƒๆœ‰็›ฃ่ฝ message ไบ‹ไปถๆ™‚๏ผŒๅฆไธ€ๅ€‹ๅŸท่กŒ็’ฐๅขƒไพฟๅฏ้€้Ž้€™ๅ€‹ๆ–นๆณ•ไพ†ๆ–ฐๅขžไธ€ๅ€‹่จŠๆฏๅˆฐ่ฉฒๅŸท่กŒ็’ฐๅขƒไธญใ€‚

็ต•ไธ้˜ปๅกž๏ผˆNever blocking๏ผ‰

ไบ‹ไปถๅพช็’ฐ้€™ๅ€‹ๆจกๅž‹ๆœ‰ไธ€ๅ€‹้žๅธธๆœ‰่ถฃ็š„็‰น่‰ฒๅฐฑๆ˜ฏๆฐธไธ้˜ปๅกž๏ผŒ้€™่ˆ‡ๅ…ถไป–่ชž่จ€ไธไธ€ๆจฃใ€‚I/O ็š„่™•็†้€šๅธธๆœƒ็ถ“็”ฑไบ‹ไปถไปฅๅŠๅ›žๅ‘ผๅ‡ฝๅผๅฏฆไฝœ๏ผŒๅ› ๆญค็•ถไธ€ๅ€‹็จ‹ๅผๆญฃๅœจ็ญ‰ๅพ… IndexedDB ็š„ๆŸฅ่ฉข็ตๆžœๆˆ–ๆ˜ฏๅ›žๅ‚ณ XHR ่ซ‹ๆฑ‚ๆ™‚๏ผŒไพ่ˆŠๅฏไปฅๅŸท่กŒๅ…ถไป–ๅƒๆ˜ฏไฝฟ็”จ่€…่ผธๅ…ฅ็š„ๅ‹•ไฝœใ€‚

ไพ‹ๅค–๏ผˆexceptions๏ผ‰ๆฐธ้ ๅญ˜ๅœจ๏ผŒๅƒๆ˜ฏ alert ๆˆ–ๆ˜ฏๅŒๆญฅ็š„ XHR๏ผŒไฝ†ๅฅฝ็š„ๅฏฆไฝœๆ–นๅผๅฐฑๆ˜ฏ้ฟ้–‹ไป–ๅ€‘ใ€‚ๅฆๅค–่ฆๆณจๆ„ๅ€‹ๆ˜ฏ๏ผŒไพ‹ๅค–็š„ไพ‹ๅค–ไธ€็›ดๆ˜ฏๅญ˜ๅœจ็š„๏ผˆไฝ†้€šๅธธ็‚บๅฏฆไฝœๆ™‚็š„้Œฏ่ชค่€Œ้žๅ…ถไป–ๆƒ…ๆณ๏ผ‰ใ€‚