<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      JavaScript – Pipeline Operator

      介紹

      Pipeline Operator (|>) 是一個很新的 JavaScript 語法,目前還在 TC39 stage 2。

      它有啥用呢?我們一起來了解一下 pipe 的前世今生。

       

      參考

      YouTube – Javascript's New Pipeline Operator Is Awesome!

       

      Pipe 的前世今生

      我們直接看例子。

      Single function

      這是一個 sum 函數

      function sum(numbers) {
        return numbers.reduce((total, number) => total + number, 0);
      }

      沒什么特別的,就是把 array 的 number 累加起來,返回一個總數,使用方式是這樣

      const numbers = [1, 2, 3, 4, 5, 6];
      const total = sum(numbers); 
      console.log(total); // 21

      好,再一個 removeOdd 函數

      function removeOdd(numbers) {
        return numbers.filter(number => number % 2 === 0);
      }

      也沒什么特別的,就是把 array 里的單數刪除,只留下雙數,使用方式是這樣

      const numbers = [1, 2, 3, 4, 5, 6];
      const evenNumbers = removeOdd(numbers); 
      console.log(evenNumbers); // [2, 4, 6]

      Combine function

      那如果我想要先 "刪除單數 removeOdd" 接著 "累加 sum" 該怎么寫呢?

      const numbers = [1, 2, 3, 4, 5, 6];
      
      const evenNumbers = removeOdd(numbers); // [2, 4, 6]
      const total = sum(evenNumbers); 
      
      console.log(total); // 12

      簡單,我們可以先調用 removeOdd 獲得雙數,接著再把雙數拿去 sum,這樣就獲得總數了。

      等等...這代碼有點啰嗦丫。

      讓我們把它們連寫在一起看看。

      const numbers = [1, 2, 3, 4, 5, 6];
      const total = sum(removeOdd(numbers)); // 12

      呃...代碼雖然是正確,但看上去不好理解,因為我們的邏輯是先 removeOdd 然后才 sum,但代碼看上去的順序卻是顛倒的,先 sum 然后 removeOdd,一點都不直觀。

      Method chaining

      我們回過頭看看原生 Array 方法的調用方式

      const numbers = [1, 2, 3, 4, 5, 6];
      
      const total = numbers
        .filter(number => number % 2 === 0) // removeOdd
        .reduce((total, number) => total + number, 0); // sum
      
      console.log(total); // 12

      看到嗎,代碼的順序和要執行的邏輯是一致的,這才符合直覺。

      那我們有辦法也寫成這樣嗎?

      有,擴展 Array prototype 就可以了。

      function sum(numbers) {
        return numbers.reduce((total, number) => total + number, 0);
      }
      
      function removeOdd(numbers) {
        return numbers.filter(number => number % 2 === 0);
      }
      
      Array.prototype.sum = function() {
        return sum(this);
      }
      
      Array.prototype.removeOdd = function() {
        return removeOdd(this);
      }
      
      const numbers = [1, 2, 3, 4, 5, 6];
      const total = numbers.removeOdd().sum();
      console.log(total); // 12

      RxJS 6.0 以前的寫法就采用了 method chaining 方式,像這樣

      // Import the necessary operators from RxJS 5
      import { Observable } from 'rxjs';
      import 'rxjs/add/operator/map';
      import 'rxjs/add/operator/filter';
      import 'rxjs/add/operator/reduce';
      
      // Create an observable that emits numbers from 1 to 5
      const numbers$ = Observable.of(1, 2, 3, 4, 5);
      
      // Chain operators: filter, map, reduce
      numbers$
        .filter(num => num % 2 === 0)       // Keep even numbers
        .map(num => num * 2)                 // Double the numbers
        .reduce((acc, num) => acc + num, 0)  // Sum the numbers
        .subscribe(result => {
          console.log(result);  // Output will be 12 (i.e., (2*2) + (4*2) = 4 + 8)
        });

      Pipe function

      method chaining 寫法有一些致命的問題,比如它不支持 tree shaking 等等。

      RxJS 在 v6.0 版本中,把 method chaining 換成了 Pipe function 寫法。

      這是一個非常嚴重的 breaking changes,對用戶來說,項目中每一個使用到 RxJS 的地方都需要改代碼??。

      從這一點也可以看出 method chaining 的問題很大,所以 RxJS 才不惜代價也要改成 Pipe function。

      Pipe function 的寫法是這樣的:

      首先需要一個通用的 pipe 函數

      function pipe(source, ...pipeFns) {
        let result = source;
        for (const pipeFn of pipeFns) {
          const fnReturn = pipeFn(result);
          if (fnReturn !== undefined) {
            result = fnReturn;
          }
        }
        return result;
      }

      TypeScript 版

      type PipeFn<T, R> = (param: T) => R;
      
      function pipe<T, R1>(source: T, fn1: PipeFn<T, R1>): R1;
      function pipe<T, R1, R2>(source: T, fn1: PipeFn<T, R1>, fn2: PipeFn<R1, R2>): R2;
      function pipe<T, R1, R2, R3>(source: T, fn1: PipeFn<T, R1>, fn2: PipeFn<R1, R2>, fn3: PipeFn<R2, R3>): R3;
      function pipe<T, R1, R2, R3, R4>(
        source: T,
        fn1: PipeFn<T, R1>,
        fn2: PipeFn<R1, R2>,
        fn3: PipeFn<R3, R4>,
        fn4: PipeFn<R3, R4>,
      ): R4;
      function pipe<T, R1, R2, R3, R4, R5>(
        source: T,
        fn1: PipeFn<T, R1>,
        fn2: PipeFn<R1, R2>,
        fn3: PipeFn<R3, R4>,
        fn4: PipeFn<R3, R4>,
        fn5: PipeFn<R4, R5>,
      ): R5;
      function pipe<T, R1, R2, R3, R4, R5, R6>(
        source: T,
        fn1: PipeFn<T, R1>,
        fn2: PipeFn<R1, R2>,
        fn3: PipeFn<R3, R4>,
        fn4: PipeFn<R3, R4>,
        fn5: PipeFn<R4, R5>,
        fn6: PipeFn<R5, R6>,
      ): R6;
      function pipe<T, R1, R2, R3, R4, R5, R6, R7>(
        source: T,
        fn1: PipeFn<T, R1>,
        fn2: PipeFn<R1, R2>,
        fn3: PipeFn<R3, R4>,
        fn4: PipeFn<R3, R4>,
        fn5: PipeFn<R4, R5>,
        fn6: PipeFn<R5, R6>,
        fn7: PipeFn<R6, R7>,
      ): R7;
      function pipe<T, R1, R2, R3, R4, R5, R6, R7, R8>(
        source: T,
        fn1: PipeFn<T, R1>,
        fn2: PipeFn<R1, R2>,
        fn3: PipeFn<R3, R4>,
        fn4: PipeFn<R3, R4>,
        fn5: PipeFn<R4, R5>,
        fn6: PipeFn<R5, R6>,
        fn7: PipeFn<R6, R7>,
        fn8: PipeFn<R7, R8>,
      ): R8;
      function pipe<T, R1, R2, R3, R4, R5, R6, R7, R8, R9>(
        source: T,
        fn1: PipeFn<T, R1>,
        fn2: PipeFn<R1, R2>,
        fn3: PipeFn<R3, R4>,
        fn4: PipeFn<R3, R4>,
        fn5: PipeFn<R4, R5>,
        fn6: PipeFn<R5, R6>,
        fn7: PipeFn<R6, R7>,
        fn8: PipeFn<R7, R8>,
        fn9: PipeFn<R8, R9>,
      ): R9;
      function pipe(source: unknown, ...pipeFns: PipeFn<unknown, unknown>[]): unknown;
      function pipe(source: unknown, ...pipeFns: PipeFn<unknown, unknown>[]): unknown {
        let result = source;
        for (const pipeFn of pipeFns) {
          const fnReturn = pipeFn(result);
          if (fnReturn !== undefined) {
            result = fnReturn;
          }
        }
        return result;
      }
      View Code

      接著

      const numbers = [1, 2, 3, 4, 5, 6];
      const total = pipe(numbers, removeOdd, sum);
      console.log(total); // 12

      原理很簡單,就是拿上一個函數的 return,傳入下一個函數,以此類推。

      pipe function 是獨立的,它不需要和 prototype 有關聯,所以完全支持 tree shaking。

      pipe function with arguments

      如果我們的函數需要參數也沒問題,

      function removeOddOrEven(numbers, oddOrEven) {
        return numbers.filter(num => oddOrEven === 'odd' ? num % 2 === 0 : num % 2);
      }

      調用時需要傳入參數 oddOrEven。

      調用時 wrap 一層箭頭函數即可

      const total = pipe(numbers, numbers => removeOddOrEven(numbers, 'odd'), sum);

      或者寫一個通用的 wrapper 

      export function wrapToPipeFn(pipeFn) {
        return (...args) => value => pipeFn(value, ...args)
      }
      
      const removeOddOrEvenPipe = wrapToPipeFn(removeOddOrEven);
      
      const numbers = [1, 2, 3, 4, 5, 6];
      const total = pipe(numbers, removeOddOrEvenPipe('odd'), sum);
      console.log(total); // 12

      TypeScript 版

      function wrapToPipeFn<TArguments extends unknown[], TValue, TReturn>(
        pipeFn: (value: TValue, ...args: TArguments) => TReturn,
      ) {
        return (...args: TArguments) =>
          (value: TValue) =>
            pipeFn(value, ...args);
      }
      View Code

      RxJS > v6.0

      上一 part 我們看到的是 RxJS 5.0 的語法,采用的是 method chaining,而 v6.0 后就改成 pipe function 了。

      // Import the necessary operators from RxJS 7
      import { of } from 'rxjs';
      import { filter, map, reduce } from 'rxjs/operators';
      
      // Create an observable that emits numbers from 1 to 5
      const numbers$ = of(1, 2, 3, 4, 5);
      
      // Chain operators using pipe
      numbers$
        .pipe(
          filter(num => num % 2 === 0),      // Keep even numbers
          map(num => num * 2),                // Double the numbers
          reduce((acc, num) => acc + num, 0)  // Sum the numbers
        )
        .subscribe(result => {
          console.log(result);  // Output will be 12 (i.e., (2*2) + (4*2) = 4 + 8)
        });

       

      Pipeline Operator (|>)

      主角登場????

      了解了 pipe function,再來看 Pipeline Operator 就很簡單了。

      這一句

      const total = pipe(numbers, removeOdd, sum);

      改成這樣

      const total = numbers |> removeOdd |> sum;

      效果一模一樣,這就是 JS 的 Pipeline Operator 語法。

      去掉 pipe 函數調用,然后把逗號 (,) 換成 pipe 箭頭 (|>)。

      這一句

      const total = pipe(numbers, (numbers) => removeOddOrEven(numbers, 'odd'), sum);

      改成這樣

      const total = numbers |> numbers => removeOddOrEven(numbers, 'odd') |> sum;

      效果一模一樣。

      此外,Pipeline Operator 還支持 async return 等等,我目前還沒有用到就不給例子了,有興趣的讀友自己玩玩唄。

       

      Babel for Pipeline Operator

      Pipeline Operator 語法還很新,需要 Babel 做轉譯。(TypeScript 還不支持,說是要等到 stage 3)

      這里簡單演示一下 Babel setup。

      創建項目

      yarn init

      安裝 Babel

      yarn add @babel/cli @babel/core @babel/preset-env --dev

      安裝插件 for Pipeline Operator

      yarn add @babel/plugin-proposal-pipeline-operator --dev

      創建 Babel config file -- babel.config.json

      {
        "presets": [
          "@babel/preset-env"
        ],
        "plugins": [
          [
            "@babel/plugin-proposal-pipeline-operator",
            {
              "topicToken": "^^",
              "proposal": "fsharp"
            }
          ]
        ]
      }

      src/main.js

      function sum(numbers) {
        return numbers.reduce((total, number) => total + number, 0);
      }
      
      function removeOdd(numbers) {
        return numbers.filter(number => number % 2 === 0);
      }
      
      function removeOddOrEven(numbers, oddOrEven) {
        return numbers.filter(num => oddOrEven === 'odd' ? num % 2 === 0 : num % 2);
      }
      
      function pipe(source, ...pipeFns) {
        let result = source;
        for (const pipeFn of pipeFns) {
          const fnReturn = pipeFn(result);
          if (fnReturn !== undefined) {
            result = fnReturn;
          }
        }
        return result;
      }
      
      function wrapToPipeFn(pipeFn) {
        return (...args) =>value => pipeFn(value, ...args)
      }
      
      const removeOddOrEvenPipe = wrapToPipeFn(removeOddOrEven);
      
      const numbers = [1, 2, 3, 4, 5, 6];
      // const total = pipe(numbers, (numbers) => removeOddOrEven(numbers, 'odd'), sum);
      const total = numbers |> numbers => removeOddOrEven(numbers, 'odd') |> sum;
      console.log('total', total); // 12
      View Code

      src/index.html

      <!DOCTYPE html>
      <html lang="en">
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
      </head>
      <body>
        <script src="/lib/main.js"></script>
      </body>
      </html>
      View Code

      執行 command

      yarn run babel src -d lib --watch

      Live Server 打開 src/index.html 就可以了

      以上。

       

      posted @ 2025-02-02 13:47  興杰  閱讀(163)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲欧美日韩在线不卡| 国产亚洲av手机在线观看| 最近中文字幕完整版hd| 毛葺葺老太做受视频| 亚洲一区久久蜜臀av| 人妻另类 专区 欧美 制服| 国产 麻豆 日韩 欧美 久久| 999国产精品999久久久久久 | 在线看免费无码的av天堂| 久9re热视频这里只有精品免费| 欧美人与动交视频在线观看| 香港日本三级亚洲三级| 中文字幕无线码免费人妻| 久久亚洲中文无码咪咪爱| 在线综合亚洲欧洲综合网站| XXXXXHD亚洲日本HD| 亚洲国产美女精品久久久| 不卡国产一区二区三区| 欧美猛少妇色xxxxx| 国产免费无遮挡吸奶头视频| 18禁亚洲一区二区三区| 成人自拍小视频在线观看| 激情亚洲专区一区二区三区| 老熟妇欲乱一区二区三区| 仙桃市| 国产成人精品亚洲午夜| 久久精品国产亚洲AV瑜伽| 男女性高爱潮免费网站| 撩起胸让我的?蹭来蹭去| 无码一区二区三区中文字幕 | 毛片久久网站小视频| 亚洲中文字幕国产综合| 91亚洲国产成人久久蜜臀| 成人亚洲国产精品一区不卡| 国产高清在线不卡一区| 风韵丰满妇啪啪区老老熟女杏吧 | 久久人妻精品大屁股一区| 在线国产精品中文字幕| 亚洲精品97久久中文字幕无码 | 中文字幕日韩一区二区不卡| 色综合 图片区 小说区|