iT邦幫忙

2022 iThome 鐵人賽

DAY 18
0
自我挑戰組

菜雞也能優雅的征服RxJS系列 第 18

菜雞也能優雅的征服RxJS - day18: 給我第一個,其餘免談 first

  • 分享至 

  • xImage
  •  

  • 延續著我們昨天介紹的take(N),今天介紹也是跟數量有關的,不過它比較有個性,只抓一個 ~ first。☕

first

RxJS官網-first

  • first定義如下:
  1. first(): default值是undefined,也就是說,我們不輸入任何值也可以,直接取出observable的第一個值。
  2. first(條件式):當偵測到observable的條件式吻合後,隨即結束。

case1: first基本式

stackblitz

import { from, first, fromEvent, map } from 'rxjs';

// 建立觀察者
const observer = {
  next: console.log,
  complete: () => console.log('completed!'),
};

// case1: first()
console.log('=== case1: first() ===)');
from([1, 2, 3, 4, 5]).pipe(first()).subscribe(observer); //<-- 偵測到第一筆資料,隨即結束

// 印出
// 1
// completed!

case2: first(條件式)

  • 這個例子我們來些不同的變化:
  1. 我們在HTML建置一個長寬各100px的點擊區
  2. javascript中,偵測click event,當clickx<100y<100的區域,也就是我們剛剛設置的點擊區,隨即結束任務。
  3. 結束任務時,於HTML中顯示completed!

stackblitz
-html

  <body>
    <div style="width: 100px; height: 100px; background-color: skyBlue"></div>
    <h2>fromEvent + first(condition)</h2>
    <p>Click blue cubic once and then completed</p>
    <p id="message" style="color: blue"></p>
  </body>
  • javascript
// case2: fromEvent + first;
console.log('=== case2: fromEvent + first(condition) ===)');
fromEvent(document, 'click')
  .pipe(
    map((event: MouseEvent) => {
      // retrieve clientX/Y
      return { x: event.clientX, y: event.clientY };
    }),
    first(({ x, y }) => x < 100 && y < 100) //<-- 當點擊的x<100且y<100,代表藍色點擊區,隨即結束
  )
  .subscribe({
    next: console.log,
    complete: () => {
      document.getElementById('message').innerHTML = 'completed!';
      console.log('completed!');
    },
  });

解析

  • 從結果來看,使用者點擊到藍色區塊外,確實不會有任何的顯示;當點擊在藍色區塊,符合條件式,隨即結束任務,並於completed的函示中,進行element的設定,顯示completed!HTML中。

Case3: 這樣做更俐落

  • 偵測點擊的方式很多,我們可以將case2稍微修改一下,讓整個程式更俐落。
  1. 我們先透過document.getElementById('click-area')取得element
  2. element放置於fromEvent的第一個參數,即形成專屬click-area藍色區塊的observable
  3. pipe中依序放入first(),並用map拆解出clientX/Y

stackblitz

// case3: fromEvent + first;
console.log('=== case3: fromEvent(element) + first(condition) ===)');
const clickArea = document.getElementById('click-area'); //<--取得element
// console.log(clickArea.id);

fromEvent(clickArea, 'click')
  .pipe(
    first(), //<--當clickArea被點擊一次,隨即結束
    map((event: MouseEvent) => {
      return { x: event.clientX, y: event.clientY };
    })
  )
  .subscribe({
    next: console.log,
    complete: () => {
      document.getElementById('message').innerHTML = 'completed!';
      console.log('completed!');
    },
  });

✍Recap

  • first():預設參數為undefined,如果不提供任何參數,抓取第一筆資料後即結束
  • first(條件式):符合條件式,即抓取第一筆資料後結束
  • takefirsr適合與fromEvent搭配,可以設計出不同的使用者操作形式。

第18天完工,今天說得有點多,很多都是基本功,花點時間釐清一下,鍛鍊一下RxJS的肌肉,看到沒~目標就在不遠處囉!!


上一篇
菜雞也能優雅的征服RxJS - day17: 設定領取數量take
下一篇
菜雞也能優雅的征服RxJS - day19: 符合條件內的才拿takeWhile
系列文
菜雞也能優雅的征服RxJS32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
蛋蛋騎兵
iT邦新手 5 級 ‧ 2023-03-24 15:04:32
take与firsr适合与fromEvent搭配

這裡有筆誤哦~

我要留言

立即登入留言