Tìm hiểu về $q và Promise trong Angular
$q và Promise trong Angular
Chắc hẳn mọi người đều đã từng nhìn thấy hoặc đã từng làm việc với $q khi sử dụng angular, chăng bạn có chắc đã nắm được hết những tính năng tuyệt với của nó mang lại như là $q.all() , $q.race(). Bài viết này mình sẽ nói về một vài điều hay ho về nó.
Promise là cái quái gì ?
Promise là một type đặc biệt của 1 Object có thể sử dụng hay để cấu trúc việc xử lý bất đồng bộ. Tại sao lại gọi nó là “Promise” có lẽ cũng giống như nghĩa của nó “hẹn ước” :)) nếu A hoàn thành thì B thực hiện, nó sẽ trả về 1 kết quả ở 1 thời điểm nào đó trong tương lai.
Một Promise có 3 trạng thái pending, resolved và rejected. Xử dụng $q trong Angular chúng ta có thể xấy dựng và xử lý được các promises của nó. (có lẽ nói đến đấy thấy hơi khó hiểu vì mình cũng ko hiểu mình đang nói cái … gì :)))
Để làm rõ cái “hồ mơ” trên thì chúng ta sẽ bắt đầu với 1 ví dụ làm quen với Promise trong ES2015.
ES5 Promises
Những cái chính đề cập tới ở đây sẽ là Promise, resolve, và reject
1
2
3
|
new Promise ( /* executor*/ function ( resolve , reject ) { . . . } ) ;
|
chúng ta chỉ cần khai báo new Promise() vào xử lý các tác vụ bất đồng bộ bên trong. Ví dụ
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
29
30
31
32
33
|
/* ES5 */
var isHaveMoney = false ;
// Promise
var willDrinkBeer = new Promise (
function ( resolve , reject ) {
if ( isHaveMoney ) {
var happy = "Happy"
resolve ( happy ) ;
} else {
var reason = new Error ( 'So bad' ) ;
reject ( reason ) ;
}
}
) ;
// call our promise
var checkMoney = function ( ) {
willDrinkBeer
. then ( function ( fulfilled ) {
// yeah chúng ta có tiền và có bia
console . log ( fulfilled ) ;
} )
. catch ( function ( error ) {
// ví hết tiền, chịu thôi !
console . log ( error . message ) ;
} ) ;
}
checkMoney ( ) ; // kết quả chắc chắn là không có tiền rồi vì ông trời set default ở trên là isHaveMoney = false; rồi :(((
|
Giới thiệu $q
$q là một thành phần của AngularJS nó giống như Promise trong ES5. vì thế chúng ta có thể thực hiện như sau:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
let promise = $ q ( ( resolve , reject ) = > {
if ( /* some async task is all good */ ) {
resolve ( 'Success!' ) ;
} else {
reject ( 'Oops... something went wrong' ) ;
}
} ) ;
promise . then ( data = > {
console . log ( data ) ;
} ) ;
|
Khác thay vì new Promise() chúng ta chỉ cần $q() và cách thực hiện của nó trong 1 service ở angular như sau :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
function MyService ( $ q ) {
return {
getSomething ( ) {
return $ q ( ( resolve , reject ) = > {
if ( /* some async task is all good */ ) {
resolve ( 'Success!' ) ;
} else {
reject ( 'Oops... something went wrong' ) ;
}
} ) ;
}
} ;
}
angular
. module ( 'app' )
. service ( 'MyService' , MyService ) ;
|
Chúng ta có thể tạo ra 1 đối tượng Promise như thế này :
1
2
3
4
5
6
7
8
9
10
11
12
13
|
function getStuff ( ) {
return $ http
. get ( '/api/stuff' ) ;
. then ( data = > {
console . log ( 'Boom!' , data ) ;
} ) ;
}
getStuff ( ) . then ( data = > {
console . log ( 'Boom!' , data ) ;
} ) ;
|
chúng ta không nên tạo ra 1 đối tượng Promise như thế này vì nó sẽ tạo ra một đối tương Promise mới từ Promise đã tồn tại :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
function getStuff ( ) {
// don't do this!
let defer = $ q . defer ( ) ;
$ http
. get ( '/api/stuff' ) ;
. then ( response = > {
// don't do this!
$ q . resolve ( response ) ;
} , reason = > {
// don't do this!
$ q . reject ( reason ) ;
} ) ;
return defer . promise ;
}
getStuff ( ) . then ( data = > {
console . log ( 'Boom!' , data ) ;
} ) ;
|
$q.defer()
Sử dụng $q.defer() như một thành phần nguyên thủy của $q, giống như cấu trúc của một Promise
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
function MyService ( $ q ) {
return {
getSomething ( ) {
let defer = $ q . defer ( ) ;
if ( /* some async task is all good */ ) {
defer . resolve ( 'Success!' ) ;
} else {
defer . reject ( 'Oops... something went wrong' ) ;
}
return defer . promise ;
}
} ;
}
|
$q.when() / $q.resolve()
Sử dụng $q.when() hoặc $q.resolve() ($q.resolve() là một alias của $q.when()) khi chúng ta muốn resolve một Promise từ Object không phải Promise.
1
2
3
4
5
6
7
8
9
10
11
|
$ q . when ( 123 ) . then ( res = > {
// 123
console . log ( res ) ;
} ) ;
$ q . resolve ( 123 ) . then ( res = > {
// 123
console . log ( res ) ;
} ) ;
|
$q.reject()
Sử dụng $q.reject() khi bạn muốn reject một Promise
1
2
3
4
5
6
7
8
9
10
11
12
|
$ httpProvider . interceptors . push ( $ q = > ( {
request ( config ) { . . . } ,
requestError ( config ) {
return $ q . reject ( config ) ;
} ,
response ( response ) { . . . } ,
responseError ( response ) {
return $ q . reject ( response ) ;
}
} ) ) ;
|
$q.all()
Khi bạn cần resolve nhiều promise một lần bằng cách truyền vào 1 array các promise, cái này sẽ thực hiện .when() sau khi resolved
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
let promiseOne = $ http . get ( '/api/todos' ) ;
let promiseTwo = $ http . get ( '/api/comments' ) ;
// Array of Promises
$ q . all ( [ promiseOne , promiseTwo ] ) . then ( data = > {
console . log ( 'Both promises have resolved' , data ) ;
} ) ;
// Object hash of Promises
// this is ES2015 shorthand for { promiseOne: promiseOne, promiseTwo: promiseTwo }
$ q . all ( {
promiseOne ,
promiseTwo
} ) . then ( data = > {
console . log ( 'Both promises have resolved' , data ) ;
} ) ;
|
$q.race()
Tương tự như $q.all() phương thức $q.race() chỉ trả về 1 promise được resolve đầu tiên, ví dụ API 1 và API 2 cùng thực hiện, API 2 được resolve trước thì nó chỉ lấy Object được trả về từ API 2.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
let promiseOne = $ http . get ( '/api/todos' ) ;
let promiseTwo = $ http . get ( '/api/comments' ) ;
// Array of Promises
$ q . race ( [ promiseOne , promiseTwo ] ) . then ( data = > {
console . log ( 'Fastest wins, who will it be?...' , data ) ;
} ) ;
// Object hash of Promises
// this is ES2015 shorthand for { promiseOne: promiseOne, promiseTwo: promiseTwo }
$ q . race ( {
promiseOne ,
promiseTwo
} ) . then ( data = > {
console . log ( 'Fastest wins, who will it be?...' , data ) ;
} ) ;
|
Kết luận
Bằng việc sử Promise và $q chúng ta có thể xử lý đựọc bất đồng bộ trong AngularJS, và sử dụng $q.all() hoặc $q.race() để xử lý các promise đã có.
Đây là những tìm hiểu của mình về Promise trong ES5 cũng như $q trong AngularJS nhằm giải quyết các vấn đề bất đồng bộ. hy vọng sẽ có ích cho mọi người.
Nếu có gì sai xót mọi người góp ý!.
Có thể bạn quan tâm:
- Tạo, Quản lý Pear Cronjob Magento
- Cảm giác lần đầu trải nghiệm Node.js
- Hướng dẫn viết module cho SugarCRM
- Internet và các khái niệm cơ bản
- E-Logistics: Công nghệ cao, thân thiện
- Hướng dẫn cài đặt và sử dụng SugarCRM 5
- Tặng mã nguồn mạng xã hội giống y Facebook
- Tạo một ứng dụng với Rails API backend và VueJs frontend
- Quản trị Wordpress toàn tập
- Thiết bị di động chiếm 20% lưu lượng mua sắm trực tuyến
- Series Bảo Mật Nhập Môn – Bảo mật cơ bản cho developer
- 3 câu lệnh hữu ích trong Javascript mà bạn nên biết
DVMS chuyên:
* Viết ứng dụng cho smartphone và máy tính bảng: iPhone, iPad , Android, Tablet, Windows Phone, Blackberry, Uber app, Grab app, mạng xã hội, vận tải thông minh, thực tế ảo, game mobile,...
* Viết ứng dụng tìm và đặt xe, các hệ thống theo mô hình kinh tế chia sẻ, uber for x, ứ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, ...
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 >>