2011-11-08 31 views
11

Có thể tránh tràn ngăn xếp trong javascript bằng cách sử dụng phương thức setTimeout để gọi hàm thay vì gọi trực tiếp không? Sự hiểu biết của tôi về setTimeout là nó sẽ bắt đầu một callstack mới. Khi tôi nhìn vào callstack của cả hai chrome và IE có vẻ như là các cuộc gọi setTimeout đang chờ đợi cho các cuộc gọi chức năng trở lại.Có gọi setTimeout xóa callstack không?

Đây có phải là tài sản của trình gỡ lỗi hoặc hiểu lầm của tôi không?

EDIT

Trong khi các câu trả lời dưới đây là đúng, vấn đề thực tế tôi đã có được liên quan đến thực tế là tôi đang gọi setTimeout (aFunction(), 10) được đánh giá aFunction ngay lập tức vì sự dấu ngoặc đơn. This question đã phân loại tôi.

+0

Chức năng truyền vào 'setTimeout' không thể được gọi trước khi chức năng đó gọi' setTimeout' trả lại. Vì vậy, có, chức năng đó bắt đầu một callstack mới. –

Trả lời

12

Tôi có thể xác nhận rằng ngăn xếp sẽ bị xóa.

Hãy xem xét kịch bản này:

function a() { 
    b(); 
} 

function b() { 
    c(); 
} 

function c() { 
    debugger; 
    setTimeout(d, 1000); 
} 

function d() { 
    debugger; 
} 

a(); 

Vì vậy, có hai breakpoint - một vào đầu chức năng c, và một ở đầu chức năng d.

stack tại breakpoint đầu tiên:

  • c()
  • b()
  • một()

stack tại breakpoint thứ hai:

  • d()

Live Demo:http://jsfiddle.net/nbf4n/1/

+0

cảm ơn vì đã chỉ cho tôi đúng hướng, tôi đã có thể giải quyết dựa trên câu trả lời của bạn, tuy nhiên tôi có một câu hỏi khác, xem http://stackoverflow.com/questions/8058996/why-does-calling-settimeout-with-parenthesis- not-start-a-new-callstack –

+0

Nếu anh chàng này đúng, câu trả lời của bạn có thể là câu trả lời đúng không? Bởi vì anh chàng này nói rằng nó luôn luôn đẩy gọi lại của bạn đến hàng đợi gọi lại đầu tiên, không phải là ngăn xếp và vì vậy nếu có lệnh đồng bộ vẫn chạy trong ngăn xếp cuộc gọi, hoặc những thứ khác trong ngăn xếp nó phải chờ đợi nhiều hơn số mili giây được chỉ định . Vì vậy, nó không phải luôn luôn là 1: 1. Điều này có thể xảy ra: hey tôi đã cho bạn 5 giây chậm trễ lý do tại sao bạn trở lại trong 7? bởi vì cuộc gọi lại phải đợi thêm một chút nữa. https://youtu.be/8aGhZQkoFbQ?t=782 – PositiveGuy

+0

Độ trễ mà bạn chỉ định thông qua đối số thứ hai của 'setTimeout' không đảm bảo rằng cuộc gọi lại sẽ được gọi tại thời điểm cụ thể đó, đúng; nhưng câu trả lời của tôi không nói rằng nó sẽ như thế. –

4

Gọi là không đồng bộ, chẳng hạn như những lời gọi từ setTimeout, thực sự tạo ra một callstack mới.

Nó không hoàn toàn rõ ràng những gì bạn mô tả khi bạn nói "Khi tôi nhìn vào callstack của cả chrome và IE có vẻ như các cuộc gọi setTimeout đang chờ đợi các cuộc gọi chức năng trở lại." Tuy nhiên, một điều bạn có thể làm là đặt một điểm ngắt bên trong một hàm gọi là setTimeout và thấy rằng callstack rỗng.

+0

Bạn có biết tại sao tôi vẫn có thể nhìn thấy toàn bộ callstack trong trình gỡ rối không? Có phải vì hàm của tôi gọi từ setTimeout sử dụng một đóng để nhận các biến cục bộ nhất định? –

+1

@AranMulholland Bạn gọi trình gỡ rối ở đâu? Bên trong hàm được truyền vào 'setTimeout'? –

+0

@ ŠimeVidas theo câu hỏi, tôi chỉ nhìn vào callstack trong trình gỡ rối trình duyệt (Chrome và IE) –

Các vấn đề liên quan