คำถามติดแท็ก event-loop

17
ทำไมบางครั้ง setTimeout (fn, 0) จึงมีประโยชน์
ฉันเพิ่งพบข้อผิดพลาดค่อนข้างน่ารังเกียจรหัสนั้นโหลด<select>แบบไดนามิกผ่านทาง JavaScript โหลดแบบไดนามิกนี้<select>มีค่าที่เลือกไว้ล่วงหน้า ใน IE6 เราแล้วมีรหัสในการแก้ไขปัญหาที่เลือก<option>เพราะบางครั้ง<select>'s selectedIndexค่าจะออกจากซิงค์กับที่เลือก<option>' s indexคุณลักษณะดังต่อไปนี้: field.selectedIndex = element.index; อย่างไรก็ตามรหัสนี้ไม่ทำงาน แม้ว่าจะselectedIndexมีการตั้งค่าฟิลด์อย่างถูกต้อง แต่ดัชนีที่ไม่ถูกต้องก็จะถูกเลือก อย่างไรก็ตามถ้าฉันติดalert()คำสั่งในเวลาที่เหมาะสมตัวเลือกที่ถูกต้องจะถูกเลือก การคิดว่านี่อาจเป็นปัญหาเรื่องเวลาฉันลองสุ่มเลือกที่ฉันเคยเห็นในรหัสมาก่อน: var wrapFn = (function() { var myField = field; var myElement = element; return function() { myField.selectedIndex = myElement.index; } })(); setTimeout(wrapFn, 0); และสิ่งนี้ได้ผล! ฉันมีวิธีแก้ไขปัญหาแล้ว แต่ฉันไม่สบายใจที่ไม่รู้ว่าทำไมสิ่งนี้ถึงแก้ไขปัญหาของฉันได้ ใครบ้างมีคำอธิบายอย่างเป็นทางการ? ฉันหลีกเลี่ยงปัญหาเบราว์เซอร์ใดโดยเรียกใช้ฟังก์ชัน "ภายหลัง" โดยใช้setTimeout()?

3
ความแตกต่างระหว่าง microtask และ macrotask ภายในบริบทของเหตุการณ์
ฉันเพิ่งอ่านข้อกำหนด Promises / A + เสร็จแล้วและสะดุดกับคำว่า microtask และ macrotask: ดูที่http://promisesaplus.com/#notes ฉันไม่เคยได้ยินคำศัพท์เหล่านี้มาก่อนและตอนนี้ฉันสงสัยว่าความแตกต่างคืออะไร? ฉันพยายามค้นหาข้อมูลบางอย่างบนเว็บแล้ว แต่ทั้งหมดที่ฉันพบคือโพสต์นี้จากคลังเก็บ w3.org (ซึ่งไม่ได้อธิบายความแตกต่างให้ฉัน): http://lists.w3.org/Archives /Public/public-nextweb/2013Jul/0018.html นอกจากนี้ฉันพบโมดูล npm ที่เรียกว่า "macrotask": https://www.npmjs.org/package/macrotask อีกครั้งยังไม่มีการชี้แจงว่าความแตกต่างคืออะไรกันแน่ สิ่งที่ฉันรู้ก็คือมันมีบางอย่างเกี่ยวข้องกับการวนซ้ำของเหตุการณ์ดังที่อธิบายไว้ในhttps://html.spec.whatwg.org/multipage/webappapis.html#task-queue และhttps: //html.spec.whatwg .org / multipage / webappapis.html # perform-a-microtask-จุดตรวจ ฉันรู้ว่าในทางทฤษฎีฉันควรจะสามารถดึงความแตกต่างออกมาได้ด้วยตัวเองตามข้อกำหนด WHATWG นี้ แต่ฉันแน่ใจว่าคนอื่น ๆ ก็อาจได้รับประโยชน์เช่นกันจากคำอธิบายสั้น ๆ ที่ผู้เชี่ยวชาญให้มา

7
Nodejs ห่วงเหตุการณ์
มีลูปเหตุการณ์สองเหตุการณ์ภายในสถาปัตยกรรม nodejs หรือไม่ libev / libuv เหตุการณ์ v8 javascript ในการร้องขอ I / O โหนดคิวจะร้องขอไปยัง libeio ซึ่งจะแจ้งความพร้อมของข้อมูลผ่านเหตุการณ์โดยใช้ libev และในที่สุดเหตุการณ์เหล่านั้นจะถูกจัดการโดย v8 event loop โดยใช้ callbacks หรือไม่ โดยพื้นฐานแล้ว libev และ libeio รวมอยู่ในสถาปัตยกรรม nodejs อย่างไร มีเอกสารใดที่ให้ภาพที่ชัดเจนของสถาปัตยกรรมภายใน nodejs หรือไม่?

3
ทำความเข้าใจกับ Event Loop
ฉันกำลังคิดถึงมันและนี่คือสิ่งที่ฉันคิดขึ้นมา: ลองดูโค้ดด้านล่างนี้: console.clear(); console.log("a"); setTimeout(function(){console.log("b");},1000); console.log("c"); setTimeout(function(){console.log("d");},0); มีคำขอเข้ามาและเอ็นจิน JS เริ่มดำเนินการโค้ดด้านบนทีละขั้นตอน สองสายแรกคือสายซิงค์ แต่เมื่อพูดถึงsetTimeoutวิธีการมันจะกลายเป็นการดำเนินการแบบ async แต่ JS กลับมาจากมันทันทีและดำเนินการต่อซึ่งเรียกว่าNon-BlockingหรือAsync. และมันยังคงทำงานอื่น ๆ ผลลัพธ์ของการดำเนินการนี้มีดังต่อไปนี้: acdb โดยพื้นฐานแล้วครั้งที่สองsetTimeoutจะเสร็จสิ้นก่อนและฟังก์ชันเรียกกลับของมันจะถูกเรียกใช้งานเร็วกว่าฟังก์ชันแรกและนั่นก็สมเหตุสมผล เรากำลังพูดถึงแอปพลิเคชันเธรดเดียวที่นี่ JS Engine ยังคงดำเนินการสิ่งนี้ต่อไปและเว้นแต่ว่าจะเสร็จสิ้นคำขอแรกจะไม่ไปที่คำขอที่สอง แต่สิ่งที่ดีคือมันจะไม่รอให้การดำเนินการบล็อกเหมือนsetTimeoutจะแก้ไขดังนั้นมันจะเร็วกว่าเพราะยอมรับคำขอที่เข้ามาใหม่ แต่คำถามของฉันเกิดขึ้นจากรายการต่อไปนี้: # 1:หากเรากำลังพูดถึงแอปพลิเคชันแบบเธรดเดียวกลไกใดที่ประมวลผลsetTimeoutsในขณะที่เอ็นจิ้น JS ยอมรับคำขอเพิ่มเติมและดำเนินการ เธรดเดี่ยวทำงานต่อไปยังคำขออื่น ๆ อย่างไร สิ่งที่ใช้ได้ผลในsetTimeoutขณะที่คำขออื่นเข้ามาและดำเนินการ # 2:หากsetTimeoutฟังก์ชันเหล่านี้ถูกเรียกใช้งานเบื้องหลังในขณะที่มีคำขอเข้ามาและกำลังดำเนินการมากขึ้นสิ่งที่ดำเนินการประมวลผลแบบ async อยู่เบื้องหลัง? สิ่งที่เราพูดถึงนี้เรียกว่าEventLoopอะไร? # 3:แต่ไม่ควรใส่วิธีการทั้งหมดEventLoopเพื่อให้สิ่งทั้งหมดถูกดำเนินการและเรียกวิธีการโทรกลับ? นี่คือสิ่งที่ฉันเข้าใจเมื่อพูดถึงฟังก์ชันการโทรกลับ: function downloadFile(filePath, callback) { blah.downloadFile(filePath); callback(); } …

5
ฟังก์ชัน Async พร้อม + =
let x = 0; async function test() { x += await 5; console.log('x :', x); } test(); x += 1; console.log('x :', x); เรียกใช้ข้อมูลโค้ดซ่อนผลลัพธ์ขยายตัวอย่างข้อมูล ค่าของxลงทะเบียนเป็นและ1 5คำถามของฉันคือ: ทำไมมูลค่าของการx 5เข้าสู่ระบบที่สอง? หากtestมีการดำเนินการหลังจากx += 1(เพราะมันเป็นฟังก์ชั่น async) แล้วค่าของ x 1 ตามเวลาที่testจะดำเนินการดังนั้นควรจะทำให้ค่าของx += await 5x 6

2
จะจัดคิว microtask ได้อย่างไรถ้าเบราว์เซอร์ไม่สนับสนุน Promises ดั้งเดิม
ควรเขียนโค้ดที่ไม่ต้องพึ่งพาช่วงเวลาของการโทรกลับทันที (เช่น microtasks vs macrotasks) แต่ลองทิ้งไว้สักครู่ setTimeoutรอคิว macrotask ซึ่งอย่างน้อยก็รอให้เริ่มจนกว่า microtasks ทั้งหมด (และ microtasks ที่วางไข่) จะเสร็จสิ้น นี่คือตัวอย่าง: console.log('Macrotask queued'); setTimeout(function() { console.log('Macrotask running'); }); Promise.resolve() .then(function() { console.log('Microtask running'); }); console.log('Microtask queued'); console.log('Last line of script'); เรียกใช้ข้อมูลโค้ดซ่อนผลลัพธ์ขยายตัวอย่างข้อมูล พฤติกรรมของ a .thenon the Promise ที่ได้รับการแก้ไขนั้นแตกต่างจากพฤติกรรมของการsetTimeoutโทรกลับทันที- Promise .thenจะทำงานก่อนแม้ว่าจะsetTimeoutถูกจัดคิวก่อน แต่เบราว์เซอร์ที่ทันสมัยเท่านั้นที่สนับสนุนสัญญา วิธีสามารถพิเศษการทำงานของ microtask คนหนึ่ง polyfilled ถูกต้องหากPromiseไม่อยู่? …

1
การเรียกขนานคำขอ HTTP 1k จะติด
คำถามคือสิ่งที่เกิดขึ้นจริงเมื่อคุณเรียกใช้คำขอ HTTP ขาออก 1k-2k ฉันเห็นว่ามันจะแก้ปัญหาการเชื่อมต่อทั้งหมดได้อย่างง่ายดายด้วยการเชื่อมต่อ 500 ครั้ง แต่การขยับขึ้นจากที่นั่นดูเหมือนจะทำให้เกิดปัญหาเนื่องจากการเชื่อมต่อถูกเปิดทิ้งไว้และแอป Node จะติดอยู่ที่นั่น ทดสอบกับเซิร์ฟเวอร์ในพื้นที่ + ตัวอย่าง Google และเซิร์ฟเวอร์จำลองอื่น ๆ ดังนั้นด้วยจุดปลายเซิร์ฟเวอร์ที่แตกต่างกันฉันได้รับเหตุผล: อ่าน ECONNRESET ซึ่งเป็นเรื่องดีที่เซิร์ฟเวอร์ไม่สามารถจัดการคำขอและส่งข้อผิดพลาดได้ ในช่วงคำขอ 1k-2k โปรแกรมจะหยุดทำงาน เมื่อคุณตรวจสอบการเชื่อมต่อที่เปิดอยู่lsof -r 2 -i -aคุณจะเห็นว่ามีจำนวนการเชื่อมต่อ X จำนวนหนึ่งที่ค้างอยู่ที่นั่น0t0 TCP 192.168.0.20:54831->lk-in-f100.1e100.net:https (ESTABLISHED)ของการเชื่อมต่อที่ให้แขวนมี เมื่อคุณเพิ่มการตั้งค่าการหมดเวลาให้กับการร้องขอสิ่งเหล่านี้อาจจบลงด้วยข้อผิดพลาดการหมดเวลา แต่ทำไมไม่เช่นนั้นการเชื่อมต่อจะถูกเก็บไว้ตลอดไปและโปรแกรมหลักจะสิ้นสุดในสถานะที่ถูกลืมบางอย่าง รหัสตัวอย่าง: import fetch from 'node-fetch'; (async () => { const promises = Array(1000).fill(1).map(async (_value, index) …
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.