【问题标题】:arrays in array formatting in javascriptjavascript中数组格式的数组
【发布时间】:2021-07-15 16:27:08
【问题描述】:

我正在尝试修复我的代码中的这个错误,但我在任何地方都找不到解决方案,所以这让我发疯了。我放弃自己尝试了,我会在这里向大家征求意见。

我正在用 javascript 制作一个简单的 ISS 跟踪器作为初学者练习。从 API 获取位置并使用 leaflet.js 将其绘制在地图上

现在我一直在画一条折线,因为我无法以正确的格式返回一个纬度数组,而且我不明白为什么。

所以我有一个异步 getISS() 函数,它在地图上绘制当前位置(工作正常)并返回当前时间戳。然后我有另一个异步函数 getISS_at_time() 返回指定时间戳的 lat,lng 位置。但有问题。我需要将所有 [lat, lng] 位置放入一个数组中以将其提供给 L.polyline 函数,但我不明白如何。

async function getISS_at_time(timestamp) {
    const api_url =
      "https://api.wheretheiss.at/v1/satellites/25544/positions?timestamps=" +
      timestamp;

    const res = await fetch(api_url);
    const data = await res.json();
    const lat = data[0].latitude;
    const lng = data[0].longitude;
    const json_data = '{"lat":' + lat + ', "lng": ' + lng + "}";

    return JSON.parse(json_data);
  }

  async function getISS() {
    const result = await fetch(api_url);
    const data = await result.json();
    const position = [data.latitude, data.longitude];

    marker.setLatLng(position);
    iss_map.setView(position, 2);

    return data.timestamp;
  }

  getISS().then((timestamp) => {
    let start = timestamp - 45 * 60;

    for (let i = 0; i < 3; ++i) {
      timestamp = start + 60 * i;

      var positions = [];
      getISS_at_time(timestamp).then((pos) => {
        //here i'm getting the lat, lng position and trying to put it in a new array
        positions[i] = [pos.lat, pos.lng];
      });
    }
    // this is a test var with a correct array format to feed to the polyline function
    var latlngs = [
      [38.91, -77.07],
      [37.77, -79.43],
      [39.04, -85.2],
    ];
    console.log(Array.isArray(positions[0]));  // returns false
    console.log(positions); // looks exactly the same as console.log(latlngs) in the Chrome console (see img)
    console.log(Array.isArray(latlngs[0])); // returns true
    console.log(latlngs);

    // works fine
    var poly = L.polyline(latlngs, { color: "red" }).addTo(iss_map);
    // draws nothing!
    var poly = L.polyline(positions, { color: "red" }).addTo(iss_map);
  });

我也尝试使用 positions.push(pos) 而不是 positions[i] = pos 但没有成功

【问题讨论】:

  • 好的,谢谢。我修复了,但没有修复错误

标签: javascript arrays


【解决方案1】:

您的代码正在访问positions,而无需等待承诺(由getISS_at_time 返回)得到解决。

以下是解决此问题的方法:

getISS().then((timestamp) => {
    let start = timestamp - 45 * 60;

    return Promise.all(Array.from({length: 3}, (_, i) => {
        return getISS_at_time(start + 60 * i).then((pos) => [pos.lat, pos.lng]);
    }));
}).then(positions => {
    console.log(Array.isArray(positions[0]));
    console.log(positions);
    var poly = L.polyline(positions, { color: "red" }).addTo(iss_map);
    // ... more code working on this data
});

由于您已经使用async await 语法,您也可以使用立即调用的async 函数来执行相同操作:

(async function () {
    let timestamp = await getISS();
    let start = timestamp - 45 * 60;
    let positions = await Promise.all(Array.from({length: 3}, async (_, i) => {
        let pos = await getISS_at_time(start + 60 * i);
        return [pos.lat, pos.lng];
    }));
    console.log(Array.isArray(positions[0]));
    console.log(positions);
    var poly = L.polyline(positions, { color: "red" }).addTo(iss_map);
    // ... more code working on this data
})(); // immediately invoked

其他备注

用字符串连接构造 JSON 格式真的很糟糕:

const json_data = '{"lat":' + lat + ', "lng": ' + lng + "}";
return JSON.parse(json_data);

相反,只需构造对象——您甚至可以为此使用快捷的对象字面量语法:

return { lat, lng };

【讨论】:

  • 好的,如果我复制并粘贴你的 Promise.all 代码就可以了!所以谢谢你。但我并不真正理解(_, i) 的语法,但我必须在第一个 .then() 中返回位置并添加第二个 .then() 但如果我只是将我的代码与 for 循环一起使用,这是有道理的在第一个 .then() 调用多个 getISS_at_time() 并将位置返回到第二个 .then() ,它也应该工作,不是吗?
  • 感谢“其他评论”,这更容易和可读!
  • for 循环将不起作用,因为它只会迭代而不等待这些承诺得到解决。 Promise.all 会将所有这些承诺作为参数,并在所有承诺都解决后解决。只有在那一刻,代码才能继续实际使用positions
  • clear,我会阅读有关 Promise.all 的信息,以了解它现在为何有效 :) 感谢您的回答!
猜你喜欢
  • 2016-10-08
  • 2023-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多