rxjs 实现动态异步调度系统
rxjs 适合处理复杂的异步调度场景, 异步调度限制器是一个非常好的例子,基于rxjs 的核心代码 只需要 不超过10行。
- 通过mergemap操作符 concurrent : 限制订阅的最大量。(当源Observable发出的内部观察变量的数量超过concurrent设置的限制时,mergeMap操作符将开始排队等待传入的内部观察变量,并在之前的内部观察变量完成后再一次订阅它们。)
- 通过defer操作符: 延迟创建可观察对象实现 异步 task的队列等待。
输出:
import React, { useState, useEffect } from 'react'; import { Subject, interval, fromEvent, of, from, defer } from 'rxjs'; import { map, scan, startWith, switchMap, takeUntil, takeWhile, mergeMap, delay } from 'rxjs/operators'; const taskSubject = new Subject(); const concurrentLimit = 2; const source = taskSubject.pipe( mergeMap((task) => defer(() => from(task())), concurrentLimit), ); source.subscribe((val) => console.log(val)); const addTask = (task) => { taskSubject.next(task); }; const Elevator = () => { return ( <div onClick={() => { addTask(() => { console.log('do task1'); return new Promise((res) => { setTimeout(() => { res({ data: 'success request 1' }); }, 3000); }); }); addTask(() => { console.log('do task2'); return new Promise((res) => { setTimeout(() => { res({ data: 'success request 2' }); }, 1000); }); }); addTask(() => { console.log('do task3'); return new Promise((res) => { setTimeout(() => { res({ data: 'success request 3' }); }, 100); }); }); addTask(() => { console.log('do task4'); return new Promise((res) => { setTimeout(() => { res({ data: 'success request 4' }); }, 1000); }); }); // addTask(() => new Promise((resolve) => setTimeout(() => resolve({ data: 'request 3' }), 100))); // addTask(() => new Promise((resolve) => setTimeout(() => resolve({ data: 'request 4' }), 1000))); }} >dd </div> ); }; export default Elevator;