尝试在JavaScript中重播GPX路线,但却在拖延航点的努力中挣扎

我有一些GPX文件,其中包含我想要在node.js脚本中重播的路线。 这是为了支持testing一个地理应用程序,所以我想重播与路线被捕获时相同的时差。 例如,如果我有这样的文件:

<?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数据库,所以我需要对每个数据点进行其他“asynchronous”处理。

我可以将数据放入一个数组中,所以我试着用一些setTimeout调用来使用一个简单的foreach循环,但是我同时发射了一堆更新,每个更新都被延迟了一段时间。 然后我尝试使用如下所示的observables:

  // waypoints is an array of the ... waypoints // Observable.from(waypoints) .zip(Observable.timer(0, 1000), x => x) .subscribe(async waypoint => { // await'ing firebase stuff }); 

这让我用less量的代码延迟每个数据点,但只有一个固定的数量,而不是使用每个航点之间的间隔。 我试图用处理数据点的variables来replace1000 ,但是却无法正常工作。

有没有另一种方法来使用observables(或其他)来获得这种行为?

我看到js实际上并不是同步工作,但是我花了很多时间在C#中,所以我并不反对使用它,而是希望学习新的东西:)

您可以使用startWithstartWith运算符发出前一个和当前的航点,然后可以使用concatMap运算符,并将延迟适当的数量的observable:

 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/bundles/Rx.min.js"></script>