-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
96 lines (80 loc) · 2.45 KB
/
index.js
File metadata and controls
96 lines (80 loc) · 2.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import React, {PureComponent, PropTypes} from 'react'
import {View} from 'react-native'
import {BehaviorSubject, Observable} from "@reactivex/rxjs";
/**
* Created by HyperSimon
*/
export default class Timer extends PureComponent {
static propTypes = {
timestamp: PropTypes.number.isRequired, // 未来的某个时间戳
timerStep: PropTypes.number, // 计时器 step, 当前默认单位是 s
timerUnit: PropTypes.number, // 计时器 unit not in use yet
binders: PropTypes.object, // 值映射对
timerFinishedListener: PropTypes.func, // 计时器计时结束的回调
};
state = {
freeTime: null,
};
subscriptions = [];
timerFinished$ = new BehaviorSubject(false); // 0 is the initial value
constructor() {
super()
}
componentWillMount() {
const endTimeStamp = this.props.timestamp
const currentTimeStramp = new Date().getTime()
const freeTime = endTimeStamp - currentTimeStramp > 0 ? endTimeStamp - currentTimeStramp : 0
this.setState({
freeTime: new Date(freeTime)
})
}
componentDidMount() {
const {timerStep, timerFinishedListener} = this.props;
// 定时器的rx实现
const timerSub = Observable
.interval(timerStep)
.timeInterval()
.map((next) => {
const freeTime = this.state.freeTime.getTime()
if (freeTime > 0) return freeTime - next.interval // get new timestamp
else return 0
})
.subscribe(newTimeStamp => {
this.setState({freeTime: new Date(newTimeStamp)})
if (newTimeStamp === 0) this.timerFinished$.next(true) // emit timer finished observable
}, error => {
// do nothing
});
const timerFinishedSub = this.timerFinished$.subscribe({
next: (isFinished) => {
if (isFinished) {
if (timerFinishedListener) timerFinishedListener()
timerSub.unsubscribe()
}
}
})
this.subscriptions.push(timerSub);
this.subscriptions.push(timerFinishedSub)
}
render() {
const {binders} = this.props
return (
<View style={{...this.props.style}}>
{React.cloneElement(this.props.children, this.makeProps(binders))}
</View>
)
}
makeProps(binders) {
const childProps = {}
for (b in binders) {
childProps[b] = binders[b](this.state.freeTime)
}
return childProps
}
componentWillUnmount() {
if (this.subscriptions) s.forEach(sub => {
if (sub) sub.unsubscribe()
}
)
}
}