- 进度条
- 示例代码
- html
- 示例代码
- 使用到的操作符
进度条
作者 @barryrowe
本食谱演示了动态进度条的创建、模拟多个请求的管理,并在每个请求完成后更新总体进度。
示例代码
(
StackBlitz
)
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { empty } from 'rxjs/observable/empty';
import { fromEvent } from 'rxjs/observable/fromEvent';
import { from } from 'rxjs/observable/from';
import {
delay,
switchMapTo,
concatAll,
count,
scan,
withLatestFrom,
share
} from 'rxjs/operators';
const requestOne = of('first').pipe(delay(500));
const requestTwo = of('second').pipe(delay(800));
const requestThree = of('third').pipe(delay(1100));
const requestFour = of('fourth').pipe(delay(1400));
const requestFive = of('fifth').pipe(delay(1700));
const loadButton = document.getElementById('load');
const progressBar = document.getElementById('progress');
const content = document.getElementById('data');
// 请求完成后更新进度条
const updateProgress = progressRatio => {
console.log('Progress Ratio: ', progressRatio);
progressBar.style.width = 100 * progressRatio + '%';
if (progressRatio === 1) {
progressBar.className += ' finished';
} else {
progressBar.className = progressBar.className.replace(' finished', '');
}
};
// 通知更新的简单辅助函数
const updateContent = newContent => {
content.innerHTML += newContent;
};
const displayData = data => {
updateContent(`<div class="content-item">${data}</div>`);
};
// 模拟5个不同时长的请求
const observables: Array<Observable<string>> = [
requestOne,
requestTwo,
requestThree,
requestFour,
requestFive
];
const array$ = from(observables);
const requests$ = array$.pipe(concatAll());
const clicks$ = fromEvent(loadButton, 'click');
const progress$ = clicks$.pipe(switchMapTo(requests$), share());
const count$ = array$.pipe(count());
const ratio$ = progress$.pipe(
scan(current => current + 1, 0),
withLatestFrom(count$, (current, count) => current / count)
);
clicks$.pipe(switchMapTo(ratio$)).subscribe(updateProgress);
progress$.subscribe(displayData);
html
<div class="progress-container">
<div class="progress" id="progress"></div>
</div>
<button id="load">
Load Data
</button>
<div id="data">
</div>
感谢 @johnlinquist 对本示例的帮助!
使用到的操作符
- concatAll
- delay
- fromEvent
- from
- scan
- share
- switchMap
- withLatestFrom