Thứ Năm, 29 tháng 5, 2014

Lập trình bất đồng bộ

Exceptions và try/catch (phương án dự phòng)

Nói đến exception và try/catch thì mình nghĩ rằng không coder nào không biết hoặc chưa từng nghe nói tới. Khi lập trình nhiều khi có những điều xảy ra ngoài ý muốn và mình muốn điều đó không ảnh hưởng gì đến ứng dụng mình đang chạy thì mình sử dụng try/catch, có thể giúp mình nhận biết được tình huống không mong muốn đó (hay còn gọi là exception – ngoại lệ), và sau đó đưa ra một phương án dự phòng (catch).
Thật ra trước giờ mình chỉ làm việc trên 2 ngôn ngữ chính đó là PHP và Javascipt thôi, nên có thể một số gì mình viết chỉ liên quan tới 2 thằng này nên các bạn thông cảm và góp ý luôn nhé !

Function getResult() {
                Try {
                                result = thisMightFail();
                } catch (e) {
                                result = recoverFromFailure(e);
                }
}

Đơn giản là hàm thisMightFail() sẽ trả về ngoại lệ (Error) nào đó và sẽ được bắt lại và một phương án dự phòng được thực hiện recoverFromFailure(e);  Tất cả đều chạy bình thường bởi vì hàm thisMightFail() chạy đồng bộ (có nghĩa là sẽ trả về một giá trị mặc định nào đó chẳng hạn). Vậy chuyện gì sẽ xảy ra khi hàm thisMightFail() được định nghĩa lại:
Function thisMightFail() {
                xhrGet(‘/getResult’, callback, errback); // ajax request
}
thisMightFail() đã chuyển từ xử lý đồng bộ sang bất đồng bộ bằng việc thực hiện một ajax request để lấy dữ liệu về. Haha, tất cả mọi thứ bắt đầu thay đổi, làm sao đây ? J
Mình sẽ quay lại block try/catch lúc đầu, và dường như chúng không còn thích hợp cho thay đổi này rồi. Nhưng đây không phải là điểm kết, vẫn còn một chút hy vọng đấy chứ, đó là chúng ta phải hỗ trợ thêm function xử lý callback cho các trường hợp có hoặc không có dữ liệu trả về.
Function thisMightFail(callback, errorback) {
                xhrGet(‘/getResult’, callback, errorback);
}

Function getResult(callback) {
                thisMightFail(callback, function(e){
                                var result = recoverFromFailure(e)
                                callback(result);
                });
}
Tip:  Nếu xử lý try/catch lúc đầu có thêm finally:
Try {
                result = thisMightFail();
} catch (e) {
                result = recoverFromFailure(e);
} finally {
                // Do something at the end
}
Và giải pháp là chúng ta phải thêm một alwaysback callback function cho thisMightFail()
Function thisMightFail(callback, errorback, alwaysback) {
                xhrGet(‘/getResult’, callback, errorback, alwaysback);
}

Tóm lại:
Chúng ta sử dụng callback function cho lập trình bất đồng bộ khi:
·         Không còn có thể sử dụng các phương thức gọi và nhận đơn giản như trước
·         Không còn có thể xử lý lỗi trả về bằng try/catch/finally