2015-12-12 21 views
5

All:Làm thế nào để quyết định lời hứa thực hiện một rồi/catch theo

Tôi khá mới để hứa, đây là một ví dụ:

var someAsyncThing = function() { 
    return new Promise(function(resolve, reject) { 
    // this will throw, x does not exist 
    resolve(x + 2); 
    }); 
}; 

var someOtherAsyncThing = function() { 
    return new Promise(function(resolve, reject) { 
    reject('something went wrong'); 
    }); 
}; 

someAsyncThing().then(function() { 
    return someOtherAsyncThing(); 
}).catch(function(error) { 
    console.log('oh no', error); 
}); 

Tôi không hoàn toàn nhận được như thế nào .Sau đó() làm việc với Promise, ngay bây giờ tôi có thể hiểu được someAsyncThing() trả lại một Promise, mà sẽ tạo ra một ngoại lệ và do đó đi đến .catch() một phần. Và nếu chúng ta thay đổi resolve(x+2)-resolve(4), sau đó nó sẽ đi để chạy someOtherAsyncThing(); và gửi lại lời hứa khác,

câu hỏi đầu tiên là nếu sự trở lại của .Sau đó() là Promise đó?

thứ hai câu hỏi, nếu trong someOtherAsyncThing() 's Promise, tôi sử dụng resolve(x+2) gây ra một ngoại lệ, sau đó nó cũng sẽ đi đến cùng .catch() phần, sau đó làm thế nào tôi có thể làm cho điều đó .catch() chỉ bắt ngoại lệ do someAsyncThing() 's lời hứa (và cùng một câu hỏi cho chuỗi .then() nếu có)?

Cảm ơn

+0

Việc bắt giữ sẽ bắt bất kỳ ngoại lệ nào trong chuỗi, để có thêm thông tin phong phú về ngoại lệ hoặc để làm điều gì đó khác tùy thuộc vào lời hứa nào đã loại trừ ngoại lệ, bạn phải từ chối với thông tin mà bạn sẽ xử lý trong khối đánh bắt. – PixMach

+0

@PixMach Cảm ơn, đã hiểu. Điều này thực sự linh hoạt và khó sử dụng nó một cách thành thạo. – Kuan

Trả lời

3

câu hỏi đầu tiên là nếu sự trở lại của .Sau đó() là Promise đó?

p.then() trả về lời hứa - luôn luôn. Nếu cuộc gọi lại được chuyển tới trình xử lý .then() trả về một giá trị, thì lời hứa mới được trả về sẽ được giải quyết cùng lúc với lời hứa của phụ huynh, nhưng sẽ được giải quyết với giá trị trả về từ trình xử lý.

Nếu trình xử lý .then() trả lời lời hứa, thì lời hứa trả về .then() không được đáp ứng/bị từ chối cho đến khi lời hứa trả về bởi trình xử lý đã được điền đầy đủ/bị từ chối. Chúng được xích lại với nhau.

Nếu trình xử lý .then() ném, thì lời hứa trả về .then() là bị từ chối với ngoại lệ là giá trị. Ném cũng giống như trả lại lời hứa bị từ chối.

nếu trong someOtherAsyncThing() 'Promise s, tôi sử dụng resolve(x+2) gây một ngoại lệ, sau đó nó cũng sẽ đi đến cùng .catch() phần, thì làm sao tôi có thể làm cho điều đó .catch() chỉ bắt ngoại lệ do someAsyncThing()' s lời hứa (và cùng một câu hỏi cho chuỗi .then() nếu có)?

Vẻ đẹp của lời hứa là lỗi truyền bá chuỗi cho đến khi được xử lý. Cách bạn dừng tuyên truyền sai ở mọi cấp độ là xử lý lỗi ở đó.

Nếu bạn muốn tách các cơ hội .catch(), thì bạn phải chỉ bắt ở mức thấp hơn. Ví dụ:

someAsyncThing().then(function() { 
    return someOtherAsyncThing().catch(function(err) { 
     // someOtherAsyncThing rejected here 
     // you can handle that rejection here and decide how you want to proceed 

     // for example, suppose you just want to handle the rejection, log it 
     // and then continue on as if there was no problem, you can just return 
     // a value here 
     return 0; 
    }); 
}).catch(function(error) { 
    console.log('oh no', error); 
}); 
+0

Cảm ơn, đã hiểu. Điều này thực sự linh hoạt và khó hiểu một chút. Bạn có bất kỳ liên kết nào nói về Lời hứa và sau đó() rất dễ hiểu không? – Kuan

+0

@Kuan - Tôi không có tài liệu tham khảo yêu thích. Điều này có vẻ như nó bao gồm mọi thứ khá tốt: http://trevorburnham.com/presentations/flow-control-with-promises/#/. Nếu bạn chỉ cần làm theo các câu hỏi ở đây với thẻ 'lời hứa', bạn cũng sẽ học rất nhiều khi bạn sẽ tìm thấy tác giả và người ủng hộ thư viện hứa hẹn lớn trả lời câu hỏi ở đây hoặc bình luận về mọi thứ. – jfriend00

+0

Cảm ơn, tôi sẽ đọc nó. – Kuan

3

Lỗi phát sinh khi lời hứa bị phát hiện.

Nếu bạn có những điều sau đây (<= chỉ chứa):

Promise1 <= Promise2.catch(e) <= Promise3 <= throw 

Sau đó Promise3 ném và từ chối. Promise2 từ chối và sau đó bị bắt. Promise1 giải quyết thành công vì nó không nhận được từ chối.

Promise1 <= Promise2.catch(e) <= Promise3 <= throw 
^ resolves^rejects   ^rejects 

Hãy nghĩ đó là thử/bắt không đồng bộ.

Promise1 = Promise.reject(err); // or throw 

Promise2 = Promise1.catch(err => { 
    // error caught 
}); 

Promise3 = Promise1.catch(err => { 
    throw err; 
    // error not caught but thrown back 
}); 

// Now Promise1 is rejected. Promise2 is resolved. Promise3 is rejected. 

Bạn cũng cần biết rằng mỗi cuộc gọi then/catch sẽ tạo một Lời hứa mới. Tôi đề nghị bạn đọc số Promises/A+ spec và giữ nó làm tài liệu tham khảo.

+0

Cảm ơn, là Promise được tạo ra bởi sau đó/bắt giống như một trả về bởi someOtherAsyncThing() trong trường hợp của tôi? – Kuan

+0

Không. Mỗi 'then/catch' tạo ra một lời hứa mới. Và mỗi 'sau đó 'gọi lại được chạy trên' nextTick', do đó, nó thậm chí không phải là một hoạt động đồng bộ. Đọc spec, nó thực sự tiện dụng :) – Louy

+0

Cũng trong trường hợp của bạn, lời hứa 'someOtherAsyncThing' thậm chí không tồn tại khi bạn gọi phương thức' catch'. Hãy nhớ rằng việc gọi 'then/catch' là một hoạt động đồng bộ trong khi nhân bản các lời hứa là một phần mềm không đồng bộ. – Louy

2

Bạn có thể catch() trên Promise nội:

a().then(function() { 
    return b().catch(function() { 
    console.log('boo'); 
    }); 
}).catch(function(error) { 
    console.log('oh no', error); 
}); 

Nếu a() Rejects, "oh no" sẽ được đăng nhập. Nếu b() từ chối, "boo" sẽ được ghi lại nhưng không được ghi lại "oh no".

+0

Cảm ơn, vì vậy về cơ bản bối cảnh của sự bắt sẽ thay đổi trong trường hợp của tôi theo những gì bên trong sau đó()? – Kuan

+0

Xem các câu trả lời khác về cách chuỗi hoạt động của Promise, họ giải thích nó khá tốt. –

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