Hỏi đáp

RxJS nhập môn

Đây là bài viết mình dich lại đến từ bài viết tiếng Nhật 「RxJS」初心者入門 – JavaScriptの非同期処理の常識を変えるライブラリ Dịch nôm na là RxJS – 1 thư viện thay đổi các nhận thức chung về xử lý bất đồng bộ của Javascript.

Trong quy trình dịch thì mình lược bỏ đi các phần chưa cần thiết hoặc là quá chi tiết theo ý mình. Nếu bạn nào quan tâm hoặc muốn đọc bản gốc thì có thể truy cập vào link sau đây.

Bạn đang xem: Rxjs la gi

Các bạn đã bao giờ nghe đến khái niệm RxJS không ?

Bạn đang đọc: RxJS nhập môn

Nói 1 cách đơn giản, RxJS là 1 thư viện rất nhiều tiện lợi cho việc xư lý bất đồng bộ (bao gồm cả việc xư lý dựa ở trên sự kiện như 1 cú click chuột). Tất nhiên thì nói 1 cách đơn giản chính là 1 thư viện “rất tiện lợi” nhưng mà ko hẳn chính là như vậy. Nếu tìm hiểu sâu hơn 1 chút, các bạn cũng sẽ có cảm thấy thư viện này mang màu sắc “đổi mới, cách tân” chứ chỉ ko dừng ở khía cạnh “tiện lợi”.

Trong bài viết này, mình cũng sẽ cố gắng giải thích một cách dễ hiểu ngay cả đối với các người mới bắt đầu mà hoàn toàn chưa biết gì về RxJS. (thú thật thì bản thân người dịch cũng là 1 beginnger về RxJS)

About ReactiveX##

「ReactiveX (Reactive Extensions)」(viêt tắt là「RX」) là 1 project C#, , và RxJS thì chính là version JS tương ứng. Dự án này đã được bắt đầu vào năm 2009 , nhà phát triển đầu tiên là Microsoft!Nói như vậy để ta có thể thấy rõ đã được tính ổn định và đáng tin cậy của library này.

Tìm hiểu thêm: Đai ốc tiếng anh là gì? Chọn mua thế nào để đạt chuẩn?

Cho đến thời điểm hiện tại thì có rất nhiều nhiều version cho các ngôn ngữ khác như Java, JavaScript, Scala, C++, Ruby, Python, Groovy, JRuby, Kotlin.

RX , và 「Observer」##

Theo mô tả , thuyết minh trong site chính thức thì ReactiveX là một thư viện thích hợp cho các ý tưởng liên quan đến Observer Patern, Iterator moop và Functional programming.

Trong RX thì Observer Patern chính là 1 khái niệm rất nhiều cơ bản. Thực tế thì tại lúc này Bạn không cần thiết phải hiểu về khái niệm rất trừu tượng này. chúng ta đọc hãy cứ tiếp tực theo dõi các phần sau, khi đọc các phần về thí dụ hay thuyết mình, cũng sẽ dần dần hiểu đã được Observer patern chính là gì.

Warm-up##

Trước khi tiếp xúc với các phần core, mình sẽ thực hiện quên một chút với thế giới của RX !!!

**Thao tác các Event như 1 Array. **###

Đầu tiên, hãy xem đoạn code dưới đây.

[1,2,3,4,5,6,7,8].filter(function(num) return num%2; ); // => [1, 3, 5, 7]

Đây chính là đoạn code trả về các số lẽ nằm trong các số thiên nhiên đến từ 1 đến 8. Quá đơn giản phải ko ?

Tiếp theo mình cũng sẽ thử viết 1 đoạn code cũng gần tương tự chỉ bằng RxJS nhưng khác biệt ở đây chính là thay đoạn xử lý Array bằng 1 Event.

Trước tiên hãy thử chạy Demo dưới đây. Click vào Click bao nhiêu lần cũng ko có xảy ra nhưng nếu ấn vào nút Alt , và Click thì ở khung Console sẽ có xuất hiện dòng thông báo.

Đoạn code này cũng sẽ như sau :

var btnClicks = sentayho.com.vnEvent($(‘#btn’), “click”); btnClicks .filter(function (value) return sentayho.com.vney; ) .subscribe(function () sentayho.com.vn(‘Holding Alt while Clicking!’); );

Ở đây, bạn có chút ý niệm gì về việc Event thì cũng khá giống Array ko ? Tất nhiên là nếu chỉ dừng lại ở 2 thí dụ ở trên thì ngoài việc tên method filter() mình đang đặt chính là giống nhau thì không có cái gì giống rồi.

Rõ ràng là khái niệm này hoàn toàn khác với Array, nhưng nếu nhìn đến từ 1 khía cạnh khác thì Event thực tế cũng là “1 điêm” phân tán nằm ở trục thời gian. Đến đây hẳn chính là chúng ta sẽ có chút liên kết giữa 2 khái niệm này rồi nhỉ. Rõ ràng tập hợp các Event riêng biệt ở trên trục thời gian có thể được xem như chính là 1 Array.

alt

Ok, đến đây mọi người sẽ thực hiện rõ việc liên tưởng này giải quyêt được việc gì? Trong Array thì có rât nhiều các xử lý như chính là filter()、map()、forEach()、reduce()、find() . Nếu có thể áp dụng đã được các xử lý này một cách tương tự cho Event thì quá hữu ích.

Trở lại với thí dụ lúc nãy về việc viết 1 method filter() cho Array Click Event. Ở đây thì kết quả sẽ chính là 1 Array chứa các Event mà mình có ấn vào nút Alt. Cuối cùng thì để output đã được ra các kết quả mong muốn đến từ Array thư được, mình dùng phương thức subscribe.

Nếu bạn đọc nào cần một giải thích trực quan hơn thì có thể tham khảo chương được viết ở đây.

Flow chính của quy trình xử lý này sẽ là như sau.

1 Event đã được sinh ra => cho qua filter() =>thỏa mãn những điều kiện cần tìm thì cho event đấy vào Array => thông báo đến subscriber

STREAM##

Cho đến bây giờ thì mình dùng khái niệm Mảng các Event cho dễ hiểu nhưng thực ra thì vẫn còn 1 cái tên khá hay là hơn cho nó chính là Stream.

Vâng, đây là Stream !!!

Tham khảo thêm: Tổng quan về UI Designer – Cẩm nang về UI Phần 1 – NordicCoder

alt

Trong Rx thì khái niệm này thường được gọi chính là Observable/Observable-Sequence. Theo mình rõ ràng chính là cách gọi Stream dễ hiêu hơn nhiều. Trong bài viết này mình sẽ sử dụng cách gọi chính là Stream. Các bạn chú ý nhé.

Trong Rx thì có rất nhiều method phục vụ cho việc create các Stream. Đây là các danh sách các phương thức đó : Create, Defer, Empty/Never/Throw, From, Interval, Just, Range, Start, Timer.

Các Operator để thao tác với Stream##

Ngoài filter ra thì có rất nhiều cá method có sắn trong RxJS hõ trợ việc thao tác với Stream như map, reduce, merge, concat, zip. các method như thế này đã được gọi chung chính là Operator.

Cho đến bây giờ thì flow xử lý cũng sẽ là:

Tạo mới 1 Stream (Observable)Truyền thêm các OperatorSubcribe

Như ở thí dụ lúc nãy, giá trị trả về đến từ sentayho.com.vnEvent() có thể xem như chính là Observable. Đối với Observable này mình có 1 Operator là (filter), cuối cùng thì các giá trị két quả cũng sẽ nhận đã được ở subscribe.

Các bạn có thể tham khảo link dưới đây để có thêm nhữn thông tin chi tiết hơn.

Operators by Categories:

Operation Chain##

Đói với Array thì Method chain cũng sẽ như dưới đây.

[1,2,3,4,5,6,7,8] .filter(function(num) return num%2; ) .map(function(num) return num*num; ); // => [1, 9, 25, 49]

Tất nhiên RxJS cũng có nguy cơ làm như vậy.

sentayho.com.vn([1, 2, 3, 4, 5, 6, 7, 8]) // Thay Array bằng Stream (Observable) .filter(function (num) //Giá trị trả về :Observable return num % 2; ).map(function (num) // Giá trị trả về:Observable return num * num; ).forEach(function (num) // `forEach` chính là alias của `subscribe`. Giá trị trả về:Diposable return sentayho.com.vn(num); ); // => 1 // => 9 // => 25 // => 49

Dưới đây là hình ảnh mình họa giải thích cho thí dụ trên.

alt

Kí tự 「|」 dấu hiệu kết thúc Stream. Graph kiểu như thế này đã được gọi chính là Marble-Diagrams. Loại Graph này rất nhiều có ích cho việc giải thích hoạt động của Operator. Tiếp tục, mọi người hãy thử dùng Operator delayWithSelector. output giá trị mỗi 50 mili giây.

// khởi tao observer để truyền vào `subscribe()` var observer = sentayho.com.vnte(function (num) // Khi có 1 giá trị mới được push vào return sentayho.com.vn(“onNext: ” + num); , function (error) // Khi có lỗi phát sinh return sentayho.com.vn(“onError: ” + error); , function () // Stream sẽ kết thúc khi tất cả các gá trị được push vào return sentayho.com.vn(‘onCompleted’); ); sentayho.com.vn([1, 2, 3, 4, 5, 6, 7, 8]) // return giá trị mỗi 500 mili giây .delayWithSelector(function (num) return sentayho.com.vnr(num * 500); ).filter(function (num) return num % 2; ).map(function (num) return num * num; ).subscribe(observer); // => onNext: 1 // => onNext: 9 // => onNext: 25 // => onNext: 49 // => onCompleted

Cho đến bây giờ thì mình chưa thuyết mình 1 điểm, đó là subscribe() có 2 kiểu truyền tham số vào.

Kiểu thứ số 1 cũng sẽ chính là Object.

var onNext = function(); // callback khi Push var onError = function(); // callback khi lỗi var onCompleted = function(); // callback khi kết thúc o.subscribe( onNext, onError, onCompleted );

Kiểu thứ 2 chính là truyền vào observer Object

o.subscribe(observer);

Observer , và Observable###

Ở mục này mọi người sẽ tìm hiểu mối quan hệ giữa Observer , và Observable.

Bạn hãy tham khảo đoạn code sample ở đưới đây. Đoạn code này sinh gây ra 1 Object Observable thông quá hàm sentayho.com.vnte(), lưu giá trị ấy vào biến source. Ở đây thì có sử dụng sentayho.com.vnxt()để sinh ra giá trị cho observe.Ở trong subscription thì có 1 hàm dispose() để làm cho mục đích nếu giá trị trả về chưa thỏa mãn thì mình cũng sẽ làm loại trừ cái Observable đó.

var source = sentayho.com.vnte(function (observer) // sử dụng `onNext` push `num` vào observer lần lượt 500 mili giây var num = 0; var id = setInterval(function () sentayho.com.vnxt(num++); , 500); setTimeout(function () sentayho.com.vnmpleted(); , 10000); return function () sentayho.com.vn(‘disposed’); clearInterval(id); ; ); var subscription = sentayho.com.vncribe( function (x) sentayho.com.vn(‘onNext: ‘ + x); , function (e) sentayho.com.vn(‘onError: ‘ + e.message); , function () sentayho.com.vn(‘onCompleted’); ); setTimeout(function () sentayho.com.vnose(); , 5000); // => onNext: 0 // => onNext: 1 // => onNext: 2 // => onNext: 3 // => onNext: 4 // => onNext: 5 // => onNext: 6 // => onNext: 7 // => onNext: 8 // => disposed

Ở thí dụ trên thì mình mới chỉ sử dụng Next. Ngoài method này ra thì việc thông báo cho subscriber mình còn có thể sử dụng các method như là Next/Error/Completed.

Cold Observable và Hot Observable###

Observable có 2 trạng thái chính là 「Cold」và「Hot」.

alt

Cold Observable##

thí dụ ở dưới thì mình dùng 2 lần subscribe() cho cùng một Observable(source). Nếu bạn quan sát log, bạn sẽ nhận thấy các Observer lấy ra giá trị từ các Sequence mới.

Mội Observer cũng sẽ lấy giá trị ra đến từ chính Observable của chính nó.

var source = sentayho.com.vnrval(1000), subscription1 = sentayho.com.vncribe( function (x) sentayho.com.vn(‘Observer 1: onNext: ‘ + x); ), subscription2; setTimeout(function () subscription2 = sentayho.com.vncribe( function (x) sentayho.com.vn(‘Observer 2: onNext: ‘ + x); ); , 2000); setTimeout(function () sentayho.com.vnose(); sentayho.com.vnose(); , 5000); // => Observer 1: onNext: 0 // => Observer 1: onNext: 1 // => Observer 1: onNext: 2 // => Observer 2: onNext: 0 // => Observer 1: onNext: 3 // => Observer 2: onNext: 1

Hot Observable##

thí dụ dưới đây thì sử dụng hàm publish(), chuyển từ Cold Observable(source)thành Hot Observable(hot). Từ log, bạn có thể thấy điểm khác biệt với Cold Observable chính là mỗi Observer cũng sẽ lấy giá trị mới nhất từ Hot Observable(hot).

「Hot Observable」thì sẽ sinh ra 1 giá trị giống nhau ở cùng 1 timing cho tất cả các Observer.

// Tạo mới Observable var source = sentayho.com.vnrval(1000); // Chuyển thành Hot Observable var hot = sentayho.com.vnish(); // Tại thời điểm này thì giá trị chưa đã được push vào var subscription1 = sentayho.com.vncribe( function (x) sentayho.com.vn(‘Observer 1: onNext: %s’, x); ); sentayho.com.vn(‘Current Time after 1st subscription: ‘ + sentayho.com.vn()); // Sau đấy 3 giây …… setTimeout(function () // sử dụng hàm `connect()` kết nối vào `source` // Ở đây thì push các giá trị lấy ra đến từ source sẽ được push vào hot observer sentayho.com.vnect(); sentayho.com.vn(‘Current Time after connect: ‘ + sentayho.com.vn()); // sau đấy 3 giây tiếp theo setTimeout(function () sentayho.com.vn(‘Current Time after 2nd subscription: ‘ + sentayho.com.vn()); var subscription2 = sentayho.com.vncribe( function (x) sentayho.com.vn(‘Observer 2: onNext: %s’, x); ); , 3000); , 3000); // => Current Time after 1st subscription: 1425834043641 // => Current Time after connect: 1425834046647 // => Observer 1: onNext: 0 // => Observer 1: onNext: 1 // => Current Time after 2nd subscription: 1425834049649 // => Observer 1: onNext: 2 // => Observer 2: onNext: 2 // => Observer 1: onNext: 3 // => Observer 2: onNext: 3 // => Observer 1: onNext: 4 // => Observer 2: onNext: 4 // => Observer 1: onNext: 5 // => Observer 2: onNext: 5 // => Observer 1: onNext: 6 // => Observer 2: onNext: 6

**About Subject **##

Tham khảo thêm: Vyan Beauty Clinic & Spa

Subject về cơ bản chính là 1 Class của RX nhưng đây chính là 1 Class rất quan trọng. Class này kế thừa đến từ cả Observable , và Observer. Do đó, nếu Subject mà nằm trong Observable thì nó cũng nằm trong Observer.

Subject kết hợp giữa Observer , Observable###

Theo như thí dụ dưới đây, tạo 1 Subject và sau đầy thì Subscribe nó. Tiếp tục, lại sư dụng lại Subject ây và Push giá trị vào Observer mà nó được tạo ra.

var subject = new Rx.Subject(); var subscription = sentayho.com.vncribe( function (x) sentayho.com.vn(‘onNext: ‘ + x); , function (e) sentayho.com.vn(‘onError: ‘ + e.message); , function () sentayho.com.vn(‘onCompleted’); ); sentayho.com.vnxt(1); // => onNext: 1 sentayho.com.vnxt(2); // => onNext: 2 sentayho.com.vnmpleted(); // => onCompleted sentayho.com.vnose();

Subject thực hiện nhiệm vụ Start Broadcasts###

Một trong số các mục đích của Subject chính là lắng nghe Broadcast. Subject cũng giống như Observable, có interface subscribe() nhưng có 1 chút khác biệt chính là subscribe() của Subject thì chưa phải để ý gì đến scheduler.

// Observable khởi tạo giá trị mỗi 1 giây var source = sentayho.com.vnrval(1000); var subject = new Rx.Subject(); // truyền vào `source` var subSource = sentayho.com.vncribe(subject); // Broadcast 1 var subSubject1 = sentayho.com.vncribe( function (x) sentayho.com.vn(‘Value published to observer #1: ‘ + x); , function (e) sentayho.com.vn(‘onError: ‘ + e.message); , function () sentayho.com.vn(‘onCompleted’); ); // Broadcast 2 var subSubject2 = sentayho.com.vncribe( function (x) sentayho.com.vn(‘Value published to observer #2: ‘ + x); , function (e) sentayho.com.vn(‘onError: ‘ + e.message); , function () sentayho.com.vn(‘onCompleted’); ); setTimeout(function () // cho kết thúc sau 5 giây sau đó sentayho.com.vnmpleted(); sentayho.com.vnose(); sentayho.com.vnose(); , 5000); // => Value published to observer #1: 0 // => Value published to observer #2: 0 // => Value published to observer #1: 1 // => Value published to observer #2: 1 // => Value published to observer #1: 2 // => Value published to observer #2: 2 // => Value published to observer #1: 3 // => Value published to observer #2: 3 // => onCompleted // => onCompleted

Subject đảm nhận chức năng Proxy###

Hãy tham khảo đoạn code dưới đây.

setTimeout(function () // khởi tạo giá trị cho subscriber của subject sau 2 giây sau đó sentayho.com.vnxt(‘from SUBJECT’); , 2000); // => Value published to observer #1: 0 // => Value published to observer #2: 0 // => Value published to observer #1: from SUBJECT // => Value published to observer #2: from SUBJECT // => Value published to observer #1: 1 // => Value published to observer #2: 1 // => Value published to observer #1: 2 // => Value published to observer #2: 2 // => Value published to observer #1: 3 // => Value published to observer #2: 3 // => onCompleted // => onCompleted

About Scheduler##

Scheduler là 1 trong các Class của RX.

Class này thực hiện nhiệm vụ quyết định「Lúc nào có thể bắt đầu Subscribe ?」 「lúc nào giá trị được khởi tạo ?」

Hãy tham khảo đoạn code đưới đây.

// Tạo mới Observable var source = sentayho.com.vnte(function (observer) sentayho.com.vn(‘subscribe function’); var i = 0; while (i++ < 3) sentayho.com.vnxt(i); sentayho.com.vnmpleted(); ); // source = sentayho.com.vncribeOn(Rx.Scheduler.timeout); // source = sentayho.com.vnrveOn(Rx.Scheduler.timeout); sentayho.com.vn(‘in-between’); sentayho.com.vncribe( function (num) sentayho.com.vn(‘onNext: ‘ + num); , null, function () sentayho.com.vn(‘completed!’); ); sentayho.com.vn(‘EOF’); // => in-between // => subscribe function // => onNext: 1 // => onNext: 2 // => onNext: 3 // => completed! // => EOF

Thứ tự Output hẳn chính là đúng với mọi người dự đoán. Dưới đây là hình ảnh minh họa cho thứ thự Output.

alt

Bỏ phần comment ở đoạn source = sentayho.com.vncribeOn(Rx.Scheduler.timeout);kết quả cũng sẽ như thế này

// => in-between // => EOF // => subscribe function // => onNext: 1 // => onNext: 2 // => onNext: 3 // => completed!

Các hàm cũng sẽ được ưu tiên sử dụng theo thứ tự như dưới đây.

setImmediatenextTickpostMessageMessageChannelscript readystatechangedsetTimeout

Ví dự như nếu trong sentayho.com.vn thì sẽ chưa phải là setTimeout mà sẽ sử dụng setImmediate hoặc là nextTick. Việc làm này sẽ giúp cho hạn chế được việc block UI khi có các xử lý nặng.

Tiếp tục, bạn hãy thử comment out dòng source = sentayho.com.vncribeOn(Rx.Scheduler.timeout);, bỏ comment ở đoạn source = sentayho.com.vnrveOn(Rx.Scheduler.timeout);

// => in-between // => subscribe function // => EOF // => onNext: 1 // => onNext: 2 // => onNext: 3 // => completed!

Nguyên lý ở đây cũng tương tự như trên. Đoạn xử lý onNext sẽ đã được cho vào Queue , và gọi Loop Event tiếp theo đến từ Queue.

** các chủng loại Scheduler **###

Có 3 loại Scheduler

timeoutSchedulerimmediateSchedulercurrentThreadScheduler

** một vài thí dụ minh họa **##

Tạm thời đến đây thì các bạn đã nắm đã được hết các khái niệm cơ bản của RxJS. Dưới đây mình sẽ cung ứng một vài thí dụ mẫu để các bạn có thể hiểu thêm về RxJS.

** thí dụ 1 : **###

các Operator đã được sử dụng:

flatMaptakeUntil

Thuyết minh : sử dụng flatMap, chuyển từ event mousedown về event mousemove liên tục cho đến khi mouseup

(function() var $box, box_width, mousedown_events, mousemove_events, mouseup_events, source; $box = $(‘#box’); mouseup_events = sentayho.com.vnEvent($box, ‘mouseup’); mousemove_events = sentayho.com.vnEvent(document, ‘mousemove’); mousedown_events = sentayho.com.vnEvent($box, ‘mousedown’); source = sentayho.com.vnMap(function(event) var start_left, start_pageX, start_pageY, start_top; start_pageX = sentayho.com.vnX; start_pageY = sentayho.com.vnY; start_left = parseInt($box.css(‘left’)); start_top = parseInt($box.css(‘top’)); $box.addClass(‘hovering’); return sentayho.com.vn(function(e) return left: start_left + (e.pageX – start_pageX), top: start_top + (e.pageY – start_pageY) ; ).takeUntil(mouseup_events); ); sentayho.com.vncribe(function() $box.removeClass(‘hovering’); ); sentayho.com.vncribe(function(pos) sentayho.com.vn($box, left: sentayho.com.vn, top: sentayho.com.vn ); ); )();

thí dụ 2 :##

các Operator đã được sử dụng:

combinelLatest

Thuyết minh : sử dụng BehaviorSubject để thay đổi UI. BehaviorSubject cũng sẽ lấy ra giá trị được khởi tạo gần nhất. Sau đó sử dụng combineLatest để tổng hợp các giá trị củaBehaviorSubject. Nếu so sánh với jQuery thì cũng công việc nhưng với RxJs việc xử lý cũng sẽ dễ hơn nhiều.

(function () var $color, $combined, $h1, $size, $text, bind, color, size, text; $h1 = $(‘h1’); $text = $(‘.text>input’); $size = $(‘.size>input’); $color = $(‘.color>input’); $combined = $(‘#combined’); text = new Rx.BehaviorSubject($text.val()); size = new Rx.BehaviorSubject($size.val()); color = new Rx.BehaviorSubject($color.val()); sentayho.com.vncribe(function (val) $h1.text(val); ); sentayho.com.vncribe(function (val) $h1.css(‘font-size’, val + ‘px’); ); sentayho.com.vncribe(function (val) $h1.css(‘color’, val); ); bind = function (eType, elem, subject) sentayho.com.vnEvent(elem, eType).subscribe(function (e) sentayho.com.vnxt(e.target.value); ); ; sentayho.com.vnineLatest(size, color, function (text, size, color) return “text: ” + text + “<br>Size: ” + size + “px<br>Color: ” + color; ).subscribe(function (val) return $combined.html(val); ); bind(‘keyup’, $text, text); bind(‘keyup change’, $size, size); bind(‘change’, $color, color); )();

** thí dụ 3 *##

các Operator đã được sử dụng:

filterconcattimeouttake

Thuyết minh : Ở đây thì tất cả các phần quan trọng nhất sẽ nằm ở hàm createCommand.

(function () var $ken, $stage, createCommand, keydowns, keys, skill; keys = left: 37, right: 39, up: 38, down: 40, a: 65, s: 83 ; keydowns = sentayho.com.vnEvent(document, ‘keydown’); /** * hàm helper để tạo command * @param Array array lưu các key được tạo thành nên từ command combination_key theo thứ tự * @param Function hàm callback làm khi mà có 1 command callback được ấn vào thành công **/ createCommand = function (combination_keys, timeout, callback) var get_source, watch; get_source = function () var source; source = sentayho.com.vny(); sentayho.com.vnach(function (keyCode, index) var this_key; this_key = sentayho.com.vner(function (e) var is_correct; is_correct = e.keyCode === keyCode; if (is_correct === false) throw Error(‘incorrect key pressed’); else return is_correct; ).take(1); if (index > 0) this_key = sentayho.com.vnout(timeout); source = sentayho.com.vnat(this_key); ); return source; ; watch = function () var source; source = get_source(); sentayho.com.vncribe(function () sentayho.com.vn(‘correct’); , function (e) sentayho.com.vn(e.message); watch(); , function () sentayho.com.vn(‘completed’); watch(); callback(); ); ; watch(); ; // xử lý animation $ken = $(‘.ken’); $stage = $(‘.stage’); skill = hadoken: function () var $fireball, tl; tl = new TimelineLite(); $fireball = $(‘<div class=”fireball”></div>’); $ken.addClass(‘hadoken’); $stage.append($fireball); tl.add(function () $fireball.addClass(‘moving’).animate( left: ‘+=250’ , 3000, ‘linear’); , 0.33).add(function () $ken.removeClass(‘hadoken’); sentayho.com.vn(‘yes’); , 0.5).add(function () $fireball.addClass(‘explode’); , 3.3); , senpukyaku: function () var tl; $ken.addClass(‘tatsumaki’); tl = new TimelineLite(); tl.add((function () $ken.removeClass(‘tatsumaki’); ), 2); ; // setting command createCommand([keys.left, sentayho.com.vn, sentayho.com.vnt, keys.a], 500, sentayho.com.vnken); createCommand([keys.right, sentayho.com.vn, sentayho.com.vn, keys.s], 500, sentayho.com.vnukyaku); )();

Các thư viện đối thủ##

Tại thời điểm hiện nay thì sentayho.com.vn chính là 1 thư viên khá giống với RxJS và cũng có thể xem là đối thủ của RxJS. Dưới góc nhìn cá nhân thì thư viện này dễ hiểu hơn RxJS về các thuật ngữ. Nếu bạn nào đã nắm được RxJS thì việc chuyển qua sử dụng thư viện này cũng khá đơn giản.

Bạn có thể tham khảo link sau đây để có thêm thông tin về việc so sánh giữa các thư viện. sentayho.com.vn/kondei/items/17e5d4867a0652911e52

Lời kết##

Bài viết lần này chính là với chủ để là “nhập môn” vì bản thân người viết (cũng như người dịch) cũng chính là các người rất mới đối với RxJS. Đơn thuần là cảm giác có hứng thú với Reactive Programming nên tìm hiểu. Một mục đích chính khác nữa mà mình viết bài viết này cũng chính là muốn phổ cập RxJS, đưa RxJS đến với nhiều người hơn.

Tham khảo thêm: Lương khô bay sản phẩm đã được lựa chọn nhiều số 1 – Hà Nội – Quận Cầu Giấy – Ẩm thực – VnExpress Rao Vặt

Tài liệu tham khảo##

RxJS sentayho.com.vn/Reactive-Extensions/RxJSRxJS GitBook sentayho.com.vn/rx-book/Operators By Category sentayho.com.vn/documentation/operators.htmlRx Marbles sentayho.com.vn/The introduction to Reactive Programming you’ve been missing sentayho.com.vn/staltz/868e7e9bc2a7b8c1f754Learn RxJS sentayho.com.vn/jhusain/learnrxThe Reactive Extensions for JavaScript (RxJS) Examples sentayho.com.vn/Reactive-Extensions/RxJS/tree/master/examplesPrinciples of Reactive Programming sentayho.com.vn/course/reactive?from_restricted_preview=1&course_id=971465&r=https%3A%2F%2Fclass.coursera.org%2Freactive-001Reactive Programming in JavaScript – Frontrend Final Conference sentayho.com.vn/develop/javascript/e657-reactive_programming_in_javascript.htmlFunctional reactive programming sentayho.com.vn/entry/20100109/1263059731Reactive programming sentayho.com.vn/jp/news/2013/09/reactive-programming-emergingReactive programming on the Web front-end sentayho.com.vn/blog/?p=830sentayho.com.vn & Reactive Extensions for JavaScript(RxJS) sentayho.com.vn/2010/12/20_290.htmlReactive Extensions sentayho.com.vn/2011/11/hello-reactive-extensions.htmlReactive Extensions(Rx) sentayho.com.vn/fdotnet/introrx/index/index.htmlSo sánh các thư viện FRP sentayho.com.vn/kondei/items/17e5d4867a0652911e52Data-binding Revolutions with sentayho.com.vnrve() sentayho.com.vn/en/tutorials/es7/observe/

Bạn thấy bài viết thế nào?

Tìm hiểu thêm: Hướng Dẫn Cách Đánh Tài Xỉu Bóng Đá Và Mẹo Tài Xỉu Hay