我有很多GPX文件包含我想在node.js脚本中重播的路由。这是为了支持测试地理应用程序,因此我希望以与捕获路径时相同的时间差重放路点。例如,如果我有这样的文件:
<?xml version="1.0" encoding="UTF-8"?>
<gpx
version="1.1"
creator="Runkeeper - http://www.runkeeper.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.topografix.com/GPX/1/1"
xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd"
xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1">
<trk>
<name><![CDATA[Running 7/9/13 5:12 pm]]></name>
<time>2013-07-09T22:12:45Z</time>
<trkseg>
<trkpt lat="46.414311000" lon="-94.356703000"><ele>386.7</ele><time>2013-07-09T22:12:45Z</time></trkpt>
<trkpt lat="46.414328000" lon="-94.356708000"><ele>386.0</ele><time>2013-07-09T22:12:46Z</time></trkpt>
<trkpt lat="46.414404000" lon="-94.356637000"><ele>385.6</ele><time>2013-07-09T22:12:49Z</time></trkpt>
<trkpt lat="46.414486000" lon="-94.356562000"><ele>385.4</ele><time>2013-07-09T22:12:52Z</time></trkpt>
...
我希望我的脚本处理第一个点,等待1秒,然后处理第二个点,等待3秒再处理第三个点,然后再处理3秒钟再处理最后一点...依此类推。它可能根本不重要,但是我正在获取这些数据并更新一个firebase数据库,所以还有其他的#as;&#34; async&#34;我需要对每个数据点做的事情。
我可以将数据放入数组中没有问题,所以我尝试使用一个带有一些setTimeout调用的简单foreach循环,但我同时触发了一堆更新,其中每个都有一些延迟。然后我尝试使用像这样的observable:
// waypoints is an array of the ... waypoints
//
Observable.from(waypoints)
.zip(Observable.timer(0, 1000), x => x)
.subscribe(async waypoint => {
// await'ing firebase stuff
});
这让我用很少的代码延迟每个数据点,但只是固定的数量,而不是使用每个航路点之间的间隔。我试图用处理数据点的变量替换1000
,但是却无法使其工作。
有没有其他方法可以使用observables(或其他东西)来获得这种行为?
我看到js真的不能同步工作,但我花了很多时间在C#中所以我并不反对只使用它,但我希望学到新的东西:)
答案 0 :(得分:1)
您可以使用startWith
和pairwise
运算符发出前一个和当前的航点,然后可以将concatMap
运算符与延迟了适当数量的可观察值一起使用:
const waypoints = Rx.Observable.from([{
lat: 46.414311000,
lon: -94.356703000,
time: Date.parse("2013-07-09T22:12:45Z")
}, {
lat: 46.414328000,
lon: -94.356708000,
time: Date.parse("2013-07-09T22:12:46Z")
}, {
lat: 46.414404000,
lon: -94.356637000,
time: Date.parse("2013-07-09T22:12:49Z")
}, {
lat: 46.414486000,
lon: -94.356562000,
time: Date.parse("2013-07-09T22:12:52Z")
}]);
const replay = waypoints
.startWith(null)
.pairwise()
.concatMap(([previous, current]) => previous ?
Rx.Observable.of(current).delay(current.time - previous.time) :
Rx.Observable.of(current)
)
.subscribe(waypoint => console.log(waypoint));
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://unpkg.com/rxjs@5/bundles/Rx.min.js"></script>