Lỗi
Hãy nói về lỗi.
Có hai loại lỗi:
- lỗi dự kiến
- lỗi không mong muốn
- lỗi do một
Lỗi dự kiến
Lỗi dự kiến là trạng thái xảy ra sự cố nhưng bạn biết rằng nó có thể xảy ra, vì vậy bạn xử lý nó.
Đây là những thứ như đầu vào của người dùng hoặc yêu cầu máy chủ. Bạn biết người dùng có thể mắc lỗi hoặc máy chủ có thể bị hỏng, vì vậy bạn viết một số mã kiểm tra để đảm bảo rằng chương trình yêu cầu nhập lại hoặc hiển thị thông báo hoặc bất kỳ hành vi nào khác phù hợp.
Đây là những phục hồi khi xử lý. Nếu để lại, chúng trở thành lỗi không mong muốn.
Lỗi không mong muốn
Lỗi không mong muốn (lỗi) là trạng thái xảy ra lỗi do mã sai. Bạn biết rằng cuối cùng chúng sẽ xảy ra, nhưng không có cách nào để biết nơi nào và làm thế nào để đối phó với chúng bởi vì, theo định nghĩa, chúng là bất ngờ.
Đây là những thứ như lỗi cú pháp và logic. Bạn có thể có một lỗi đánh máy trong mã của bạn, bạn có thể đã gọi một hàm với các tham số sai. Chúng thường không thể phục hồi.
try..catch
Hãy nói về try..catch
.
Trong JavaScript, throw
không được sử dụng phổ biến. Nếu bạn nhìn xung quanh để tìm ví dụ về mã, chúng sẽ cách nhau rất xa và thường được cấu trúc dọc theo dòng
function example(param) {
if (!Array.isArray(param) {
throw new TypeError('"param" should be an array!');
}
...
}
Do đó, try..catch
các khối không phải là tất cả những gì phổ biến cho luồng điều khiển. Thông thường khá dễ dàng để thêm một số kiểm tra trước khi gọi phương thức để tránh các lỗi dự kiến.
Các môi trường JavaScript cũng khá dễ tha thứ, vì vậy các lỗi không mong muốn cũng thường bị bỏ qua.
try..catch
không phải là hiếm Có một số trường hợp sử dụng hay, phổ biến hơn trong các ngôn ngữ như Java và C #. Java và C # có lợi thế của các catch
cấu trúc được gõ , để bạn có thể phân biệt giữa các lỗi dự kiến và lỗi không mong muốn:
C # :
try
{
var example = DoSomething();
}
catch (ExpectedException e)
{
DoSomethingElse(e);
}
Ví dụ này cho phép các trường hợp ngoại lệ không mong muốn khác chảy lên và được xử lý ở nơi khác (chẳng hạn như bằng cách đăng nhập và đóng chương trình).
Trong JavaScript, cấu trúc này có thể được nhân rộng thông qua:
try {
let example = doSomething();
} catch (e) {
if (e instanceOf ExpectedError) {
DoSomethingElse(e);
} else {
throw e;
}
}
Không thanh lịch, đó là một phần lý do tại sao nó không phổ biến.
Chức năng
Hãy nói về các chức năng.
Nếu bạn sử dụng nguyên tắc trách nhiệm duy nhất , mỗi lớp và chức năng sẽ phục vụ một mục đích duy nhất.
Ví dụ authenticate()
có thể xác thực người dùng.
Điều này có thể được viết là:
const user = authenticate();
if (user == null) {
// keep doing stuff
} else {
// handle expected error
}
Ngoài ra, nó có thể được viết là:
try {
const user = authenticate();
// keep doing stuff
} catch (e) {
if (e instanceOf AuthenticationError) {
// handle expected error
} else {
throw e;
}
}
Cả hai đều được chấp nhận.
Hứa
Hãy nói về những lời hứa.
Lời hứa là một hình thức không đồng bộ của try..catch
. Gọi new Promise
hoặc Promise.resolve
bắt đầu try
mã của bạn . Gọi điện thoại throw
hoặc Promise.reject
gửi cho bạn catch
mã.
Promise.resolve(value) // try
.then(doSomething) // try
.then(doSomethingElse) // try
.catch(handleError) // catch
Nếu bạn có chức năng không đồng bộ để xác thực người dùng, bạn có thể viết nó dưới dạng:
authenticate()
.then((user) => {
if (user == null) {
// keep doing stuff
} else {
// handle expected error
}
});
Ngoài ra, nó có thể được viết là:
authenticate()
.then((user) => {
// keep doing stuff
})
.catch((e) => {
if (e instanceOf AuthenticationError) {
// handle expected error
} else {
throw e;
}
});
Cả hai đều được chấp nhận.
Làm tổ
Hãy nói về làm tổ.
try..catch
có thể được lồng authenticate()
Phương thức của bạn có thể có một try..catch
khối như:
try {
const credentials = requestCredentialsFromUser();
const user = getUserFromServer(credentials);
} catch (e) {
if (e instanceOf CredentialsError) {
// handle failure to request credentials
} else if (e instanceOf ServerError) {
// handle failure to get data from server
} else {
throw e; // no idea what happened
}
}
Tương tự như vậy lời hứa có thể được lồng nhau. authenticate()
Phương pháp không đồng bộ của bạn có thể sử dụng nội bộ lời hứa:
requestCredentialsFromUser()
.then(getUserFromServer)
.catch((e) => {
if (e instanceOf CredentialsError) {
// handle failure to request credentials
} else if (e instanceOf ServerError) {
// handle failure to get data from server
} else {
throw e; // no idea what happened
}
});
Vậy câu trả lời là gì?
Ok, tôi nghĩ đã đến lúc tôi thực sự trả lời câu hỏi:
Là một thất bại trong xác thực được coi là một cái gì đó bạn sẽ từ chối một lời hứa cho?
Câu trả lời đơn giản nhất tôi có thể đưa ra là bạn nên từ chối một lời hứa ở bất cứ nơi nào bạn muốn throw
ngoại lệ nếu đó là mã đồng bộ.
Nếu luồng kiểm soát của bạn đơn giản hơn bằng cách có một vài if
kiểm tra trong các then
tuyên bố của bạn , thì không cần phải từ chối một lời hứa.
Nếu luồng điều khiển của bạn đơn giản hơn bằng cách từ chối lời hứa và sau đó kiểm tra các loại lỗi trong mã xử lý lỗi của bạn, thì hãy thực hiện thay thế.
reject
và không trả về false, nhưng nếu bạn đang mong đợi giá trị là aBool
, thì bạn đã thành công và bạn nên giải quyết bằng Bool bất kể giá trị. Hứa hẹn là loại proxy cho các giá trị - chúng lưu trữ giá trị được trả về, vì vậy chỉ khi không thể lấy được giá trịreject
. Nếu không thì bạn nên làmresolve
.