Tuyển dụng
Series Javascript sida – Promise – hứa thật nhiều thất hứa thật nhiều
Bài viết này sẽ giới thiệu về khái niệm promise và các ứng dụng của nó trong javascript. Promise được sử dụng khá nhiều ở cả front-end(AngularJS) và back-end(NodeJS), do đó nắm vững khái niệm này sẽ giúp bạn rất nhiều trong việc code và … trả lời phỏng vấn.
Lưu ý: Bài viết sử dụng nhiều ngôn ngữ 16+, khuyến phụ nữ dưới 18 tuổi và trẻ em có thai không nên đọc.
Lập trình bất đồng bộ trong Javascript
Bạn nào từng làm AJAX đều biết rằng Javascript kết nối với server theo cơ chế bất đồng bộ, các hàm phía sau không đợi hàm AJAX chạy xong mà tiếp tục chạy luôn.
1
2
3
4
5
|
// Hàm ajax chạy bất đồng bộ, do đó giá trị xxxImage là undefined
var xxxImage = ajax . get ( "gaixinh.info" ) ;
console . log ( xxxImage ) ;
|
Do đó, để lấy kết quả của hàm ajax, ta phải truyền cho nó 1 callback. Sau khi hàm AJAX lấy được kết quả, nó sẽ gọi hàm callback với kết quả thu được.
1
2
3
4
5
6
7
8
9
10
11
12
|
// Truyền callback vào hàm ajax
var callback = function ( image ) {
console . log ( image ) ;
} ;
ajax . get ( "gaixinh.info" , callback ) ;
// Có thể viết gọn như sau
ajax . get ( "gaixinh.info" , function ( image ) {
console . log ( image ) ;
} )
|
Cách làm này có gì không ổn? Sử dụng callback chồng chéo sẽ làm code trở nên rối rắm, khó đọc; việc bắt exception, hiển thị lỗi trở cũng nên phức tạp.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
// Do javascript bất đồng bộ, bạn không thể lấy dữ liệu lần lượt kiểu này
var xe = xin _mẹ _mua_xe ( ) ; // Chờ cả năm mới có xe
var gá i = chở _gá i _đ i _chơ i ( xe ) ; // Lấy xe chở gái đi chơi
var abcd = chở _gá i _và o_hotel ( y ) ; // Đi chơi xong chở gái đi đâu đó
// Mà phải sử dụng đống callback "gớm ghiếc", tạo thành callback hell
xin _mẹ _mua_xe ( function ( xe ) {
chở _gá i _đ i _chơ i ( xe , function ( gá i ) {
chở _gá i _và o_hotel ( hotel , function ( z ) {
// Làm gì đó, ai biết
} ) ;
} ) ;
} ) ;
|
Để giải quyết vấn đề này, các bác developer đã sáng tạo ra một khái niệm gọi là promise.
Promise là chi? Promise là… lời hứa!
Khái niệm promise được MDN giải thích một cách khá mù mờ và hơi… khó hiểu:
1
2
3
|
The < strong > < code > Promise < / code > < / strong > object is used for asynchronous computations . A < code > Promise < / code > represents an operation that hasn' t completed yet , but is expected in the future .
|
Để dễ hiểu, mình gọi Promise là lời hứa. Tương tự như trong thực tế, có người hứa rồi làm, có người hứa rồi … thất hứa.
Một lời hứa có 3 trạng thái sau:
- pending: Hiện lời hứa chỉ là lời hứa suông, còn đang chờ người khác thực hiện
- fulfilled: Lời hứa đã được thực hiện
- reject: Bạn đã bị thất hứa, hay còn gọi là bị “xù”
Khi xưa, để dụ bạn cố gắng học hành, bố mẹ bảo “Ráng đậu đại học bố mẹ sẽ mua cho con BMW đi học cho bằng bạn bằng bè”. Lúc này, thứ bạn nhận được là một lời hứa, chứ không phải xe BMW.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
// Hàm này trả ra lời hứa chứ không phải chiếc BMW
function hứ a_cho _có ( ) {
return Promise ( ( thuc_hien_loi_hua , that_hua ) = > {
// Sau 1 thời gian dài dài dàiiiiiii
// Nếu vui bố mẹ sẽ thực hiện lời hứa
if ( vui ) {
thuc_hien_loi_hua ( "Xe BMW" ) ;
// Lúc này trạng thái của lời hứa là fulfilled
} else {
that_hua ( "Xe dap" ) ;
// Lúc này trạng thái của lời hứa là rejected
}
} ) ;
}
// Lời hứa bây giờ đang là pendding
// Nếu được thực hiện, bạn có "Xe BMW"
// Nếu bị reject, bạn có "Xe đạp"
var promise = hứ a_cho _có ( ) ;
promise
. then ( ( xe_bmw ) = > {
console . log ( "Được chiếc BMW vui quá" ) ;
} )
. catch ( ( xe_dap ) = > {
console . log ( "Được chiếc xe đạp ...." ) ;
} ) ;
|
Khi lời hứa được thực hiện, promise sẽ gọi callback trong hàm then. Ngược lại, khi bị thất hứa, promise sẽ gọi callback trong hàm catch.
Quay lại với ví dụ ở đầu bài. Lúc này hàm ajax sẽ trả ra một lời hứa. Hàm này hứa là “Nếu lấy ảnh XXX, ta sẽ đưa cho mày”. Lúc này kết quả của hàm là một promise, chứ không phải là ảnh XXX.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
function get ( url ) {
return new Promise ( ( resolve , reject ) = > {
// Lấy hình từ gái xinh.com
// Nếu bị lỗi thì đành thất hứa
if ( error ) reject ( "Error" ) ;
// Nếu lấy được thì thực hiện lời hứa
resolve ( xxxImage ) ;
} ) ;
}
var promise = ajax . get ( "gaixinh.info" ) ;
// Có hình thì fap, không có thì alert lỗi
promise
. then ( image = > fap )
. catch ( ( error ) = > alert ( error ) ) ;
|
Ủa, cũng là dùng callback thôi mà??
Ừ, hồi mới tìm hiểu về promise mình cũng nghĩ tương tự như các bạn vậy đó. Vậy thì promise có gì hay mà phải dùng?
Promise hay ở các điểm sau:
- Promise hỗ trợ “chaining”
- Promise giúp bắt lỗi dễ dàng hơn
- Xử lý bất đồng bộ
Cùng phân tích các điểm hay của Promise nhé.
1. Promise chaining
Giá trị trả về của hàm then là 1 promise khác. Do vậy ta có thể dùng promise gọi liên tiếp các hàm bất đồng bộ. Có thể viết lại hàm phía trên như sau:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
// Dùng callback hell
xin _mẹ _mua_xe ( function ( xe ) {
chở _gá i _đ i _chơ i ( xe , function ( gá i ) {
chở _gá i _và o_hotel ( hotel , function ( z ) {
// Làm gì đó, ai biết
} ) ;
} ) ;
} ) ;
// Dùng promise, code gọn nhẹ dễ đọc
xin _mẹ _mua _xe
. then ( chở _gá i _đ i _chơ i )
. then ( chở _gá i _và o_hotel )
. then ( function ( ) { /*Làm gì đó, ai biết*/ } ) ;
|
2. Bắt lỗi với promiseTrong ví dụ trên, ta gọi lần lượt 3 hàm:xin_mẹ_mua_xe, chở_gái_đi_chơi, chở_gái_vào_hotel.
Chỉ cần một trong 3 hàm này bị lỗi, promise sẽ chuyển qua trạng thái reject. Lúc này callback trong hàm catch sẽ được gọi. Việc bắt lỗi trở nên dễ dàng rất nhiều
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
// Khi một function bị lỗi, promise bị reject (thất hứa)
function chở _gá i _và o_hotel ( ) {
return Promise ( ( response , reject ) = > {
reject ( "Xin lỗi hôm nay em đèn đỏ" ) ;
} ) ;
}
xin _mẹ _mua _xe
. then ( chở _gá i _đ i _chơ i )
. then ( chở _gá i _và o_hotel )
. then ( function ( ) { /*Làm gì đó, ai biết*/ } )
. catch ( function ( err ) {
console . log ( err ) ; //"Xin lỗi hôm nay em đèn đỏ"
console . log ( "xui vl" ) ;
} ) ;
|
3. Xử lý bất đồng bộ
Giả sử bạn muốn 3 hàm AJAX khác nhau. Bạn cần kết quả trả về của 3 hàm này trước khi tiếp tục chạy. Với callback, việc này sẽ khá khó thực hiện. Tuy nhiên, promise hỗ trợ hàm Promise.all, cho phép gộp kết quả của nhiều promise lại với nhau.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
// Ba hàm này phải được thực hiện "cùng lúc"
// chứ không phải "lần lượt"
var sờ _trê n = new Promise ( ( resolve , reject ) = > {
resolve ( "Phê trên" ) ;
} ) ;
var sờ _dướ i = new Promise ( ( resolve , reject ) = > {
resolve ( "Phê dưới" ) ;
} ) ;
var sờ _tù m_lum = new Promise ( ( resolve , reject ) = > {
resolve ( "Phê tùm lum chỗ" ) ;
} ) ;
// Truyền 1 array chứa toàn bộ promise vào hàm Promise.all
// Hàm này trả ra 1 promise, tổng hợp kết quả của các promise đưa vào
Promise . all ( [ sờ _trê n , sờ _dướ i , sờ _tù m_lum ] )
. then ( function ( result ) {
console . log ( result ) ; // ["Phê trên", "Phê dưới", "Phê tùm lum chỗ"]
// Phê xong làm gì ai biết
} )
|
Tổng kết
Với các ưu điểm của mình, promise đang dần dần thay thế cho callback. Dĩ nhiên là không thay thế hoàn toàn đâu. Với các hàm đơn giản thì dùng callback sẽ ngắn và dễ hiểu hơn promise.
Promise được sử dụng nhiều trong AngularJS và một số module của NodeJS. Nắm vững khái niệm promise sẽ giúp bạn code đỡ cực hơn nhiều.
Hiện tại, các bạn có thể dùng Promise trong trình duyệt Chrome và các bản NodeJS mới nhất. Với các trình duyệt khác, các bạn phải thêm thư viện promise-polyfill thì mới sử dụng được.
- Hệ thống chấm công từ xa thông minh SAttendance và hệ thống định vị STracking
- Hệ thống order chuyên nghiệp cho quán ăn, cafe, nhà hàng...
- Hệ thống giới thiệu sản phẩm, dịch vụ thông minh SCatalog và SBrochure ( hệ thống catalog và brochre thông minh trên smartphone và tablet)
- Tra cứu tàu biển
- Giải pháp cho dịch vụ bác sĩ gia đình
- Hệ thống đánh giá thông minh trên smartphone và tablet
- Ứng dụng Smartphone cho thể dục, thể thao?
- app hẹn lịch chăm sóc sắc đẹp, book vé spa, massage
- Thông tin Du Lịch có ngay trong túi mọi người
- Tự động Kiểm tra thông tin người gọi đến | Call Look
- Phòng khám, bệnh viện thông minh
- Phần mềm quản lý cho thuê xe ô tô thường có những tính năng gì?
DVMS chuyên:
- Tư vấn, xây dựng, chuyển giao công nghệ Blockchain, mạng xã hội,...
- Tư vấn ứng dụng cho smartphone và máy tính bảng, tư vấn ứng dụng vận tải thông minh, thực tế ảo, game mobile,...
- Tư vấn các hệ thống theo mô hình kinh tế chia sẻ như Uber, Grab, ứng dụng giúp việc,...
- Xây dựng các giải pháp quản lý vận tải, quản lý xe công vụ, quản lý xe doanh nghiệp, phần mềm và ứng dụng logistics, kho vận, vé xe điện tử,...
- Tư vấn và xây dựng mạng xã hội, tư vấn giải pháp CNTT cho doanh nghiệp, startup,...
Vì sao chọn DVMS?
- DVMS nắm vững nhiều công nghệ phần mềm, mạng và viễn thông. Như Payment gateway, SMS gateway, GIS, VOIP, iOS, Android, Blackberry, Windows Phone, cloud computing,…
- DVMS có kinh nghiệm triển khai các hệ thống trên các nền tảng điện toán đám mây nổi tiếng như Google, Amazon, Microsoft,…
- DVMS có kinh nghiệm thực tế tư vấn, xây dựng, triển khai, chuyển giao, gia công các giải pháp phần mềm cho khách hàng Việt Nam, USA, Singapore, Germany, France, các tập đoàn của nước ngoài tại Việt Nam,…
Quý khách xem Hồ sơ năng lực của DVMS tại đây >>
Quý khách gửi yêu cầu tư vấn và báo giá tại đây >>