2014-06-11 44 views
31

Tôi đang xử lý khung NodeJs yêu cầu một hàm nhất định phải đồng bộ, nhưng tôi cần lấy một giá trị chỉ có thể truy cập không đồng bộ. Trong một thế giới hoàn hảo, tôi sẽ có thể trả lời một lời hứa, nhưng tôi không thể.Làm cách nào để chờ lời hứa được giải quyết?

Là một giải pháp nhanh chóng-và-bẩn, tôi đã tạo ra phương pháp sau đây:

exports.synchronizePromise = function(promise) { 
    var value; 
    promise.then(function(promiseValue) { 
     value = promiseValue; 
    }); 
    while (!value) {} // Wait for promise to resolve 
    console.log("DONE: " + value); // Never reached 
    return value; 
}; 

Nhưng tôi nhận được một lỗi. Có cách nào để hoàn thành những gì tôi cần không?

+4

hứa hẹn sẽ không làm cho mọi thứ được đồng bộ hóa một cách kỳ diệu, chúng chỉ thực hiện một số quy trình không đồng bộ dễ dàng hơn để mã và quản lý thông qua nhiều bước. không sử dụng vòng lặp để cố gắng đóng băng, chỉ cần khắc phục sự cố ngược dòng bằng cách chia nhỏ mọi thứ được đồng bộ hóa thành hai phần. – dandavis

+2

@ dandavis Tôi đã cân nhắc tạo một cam kết cho khung làm việc mà tôi đang sử dụng để làm cho nó có thể hoạt động không đồng bộ, nhưng nó được gọi ở quá nhiều vị trí và 99% thời gian, nó không cần phải bằng cách không đồng bộ. Nó không thực sự là một lựa chọn để sửa chữa nó ngược dòng. –

+0

bạn ngay lập tức có thể trả lại một guid sau khi gửi quá trình, và khi quá trình hoàn tất, hãy tìm guid trong dữ liệu/dom của bạn và thay thế cho giá trị thực tế. – dandavis

Trả lời

2

Trong Q nếu bạn có một lời hứa giải quyết, bạn có thể chỉ cần lấy giá trị với kiểm tra

exports.synchronizePromise = function(promise) { 
    var i = promise.inspect(); 
    if (i.state === "rejected") { 
     throw i.reason; 
    } else if (i.state === "fulfilled") { 
     return i.value; 
    } else { 
     throw new Error("attempt to synchronize pending promise") 
    } 
}; 

Tuy nhiên, nếu lời hứa đang chờ, nó thực sự là không đồng bộ và câu hỏi của bạn không sau đó có ý nghĩa và chức năng sẽ ném một lỗi.

+0

Cảm ơn. Tôi quên rằng NodeJs là đơn luồng, vì vậy tôi nghĩ rằng tôi chỉ có thể chờ đợi cho đến khi nó được giải quyết. –

+0

@ sinθ bạn có thể đợi cho đến khi nó được giải quyết, đó là những gì '.then' là, chỉ cần đặt lệnh gọi hàm đó bên trong khối' .then'. –

+0

Làm cách nào để kiểm tra giá trị của lời hứa đã được giải quyết trợ giúp ở đây? –

-1

Lời hứa là không đồng bộ. Chúng đại diện cho một giá trị tương lai - một giá trị có sẵn trong 1ms hoặc 1 phút hoặc 1 ngày hoặc 1 năm trong tương lai hoặc không bao giờ. Theo định nghĩa, không có cách nào để "buộc" họ phải giải quyết, ngoài một cỗ máy thời gian.

Nếu bạn có logic ngược dòng được xây dựng trên tiền đề của đồng bộ, nhưng vì bất kỳ lý do gì nó tùy thuộc vào bây giờ không đồng bộ, bạn phải cấu trúc lại thành phần ngược dòng để hoạt động không đồng bộ. Không có lựa chọn nào khác.

Nếu khuôn khổ của bạn "yêu cầu một chức năng nhất định để đồng bộ" khi chức năng đó không hoặc không thể đồng bộ, thì khung được thiết kế kém và không sử dụng được hoặc ít nhất không thể sử dụng được cho sự cố của bạn.

+13

Trong khi một điểm hợp lệ, nó là tiếp tuyến với câu hỏi thực tế, đó là về giải quyết lời hứa. Lời hứa giải quyết có giá trị vượt quá trường hợp sử dụng cụ thể này. – Siddhu

+0

@siddhuwarrier Không hoàn toàn chắc chắn những gì bạn đang cố gắng nói. Về cơ bản, bạn không thể giải quyết một lời hứa; lời hứa tự giải quyết (hoặc không) và tất cả những gì bạn có thể làm là chờ đợi điều đó xảy ra. Hay tôi đang thiếu một cái gì đó? Bạn có ý gì khi "giải quyết lời hứa"? –

+0

Những gì tôi đã đề cập đến là một cơ chế nhờ đó bạn có thể chờ kết quả của một hoạt động không đồng bộ để giải quyết. Ví dụ: trong Scala, ' val f = Tương lai {...}; f.map { mục => // thực hiện hành động với kết quả trong tương lai } .recover { // xử lý lỗi }; Await.result (f, 10000 mili giây); ' Một trường hợp sử dụng cho một cái gì đó như thế này là bản thân tương lai có thể kết thúc thực hiện nhiều luồng song song để tạo ra một kết quả, trong khi chủ đề chính chờ nó kết thúc. – Siddhu

3

Với nút đó theo mặc định, chỉ có chuỗi duy nhất không thực sự là cách dễ dàng để giải quyết vấn đề này. Có một mặc dù. Căn cứ vào máy phát điện/sợi, bạn có thể thêm một loại thực hiện đồng thời vào nút. Có một số waitfor implementation dựa trên đó.

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