在 svelte (#await) 中使用 async await on promise 不会返回在以后的函数调用中格式化的所需数据

Using async await on promise in svelte (#await) is not returning the desired data that is formatted in a later function call

我目前正在使用 API,但 return JSON。为了解决这个问题,我接受响应并将其推送到一个数组(同时格式化它以删除任何缩进并拆分响应中的每个数字)。然后我使用这个包含 183 个数字的数组和 运行 一个针对包含 183 个字符的数组的 for 循环来从响应中生成一个对象(带有自定义键值对)。

当我开始使用 HTML 中的数据时,事情变得混乱了。通常你可以只说 <p>{data.overallRank}</p> 但我收到对象未定义的错误。这是有道理的,因为 data = {} 直到函数 运行.

才被创建

在搜索解决方案后,我遇到了一些精巧的等待块。您可以在这里阅读它们并查看教程:https://svelte.dev/tutorial/await-blocks

在尝试实现此功能后,我有以下代码。

let playerStats = []
    let proxy = "https://cors-anywhere.herokuapp.com/"
    let url =  proxy + "https://secure.runescape.com/m=hiscore_oldschool/index_lite.ws?player=Hess"
    const data = {};
    
    let promise = getPlayer();
    async function getPlayer() {
        return await fetch(url).then((response) => response.text())
            .then((data) => {
                return data;
            });
        }

getPlayer().then((playerData) => {
// format data
  playerStats.push(playerData.replace(/\n/ig, ",").split(','));
  console.log(playerStats);

// Begin object generation
// names array shortened
let names = ["overallRank", "overallLvl", "overallXP", "attRank", ]
  
const data = {};
    for (var i = 0; i < playerStats[0].length; i++) {
        data[names[i]] = playerStats[0][i];
    }
console.log(data);
});
<main>

{#await promise}
    <p>Search for a Player...</p>
{:then data}
    <p>The data is {data}</p>
{/await}

</main>

此代码的问题是它正在打印来自 return data 的数据,return 是未格式化的数据而不是对象。

我想要 return 在第二个函数 getplayer().then()... 之后创建的对象,这样我就可以在整个 HTML.

中使用该对象

希望我解释得很好,提前感谢您的帮助。

它正在返回格式化的数据,因为 promise 函数返回的是什么。为了获取格式化数据,您必须将格式添加到 promise

的链中
async function getPlayer() {
  return await fetch(url)
    .then((response) => response.text())
    .then((playerData) => {
       // here your transformation
       // do not forget to actually return something
       return data;
    });

你实际上已经非常接近解决问题了,只是我认为对 promises 的工作方式有点困惑。

您需要做的就是在提取和解码操作之后处理数据的块中格式化数据:

  async function getPlayer() {
    return await fetch(url)
      .then((response) => response.text())
      .then((data) => {
        return formatData(data);
      });
  }

您的 formatData() 功能基本上已经存在,您只需要对代码进行微小的更改:

  function formatData(playerData) {
    playerStats.push(playerData.replace(/\n/ig, ",").split(','));
    console.log(playerStats);

    // Begin object generation
    // names array shortened
    let names = ["overallRank", "overallLvl", "overallXP", "attRank", ]
  
    const data = {};
    for (var i = 0; i < playerStats[0].length; i++) {
      data[names[i]] = playerStats[0][i];
    }
    console.log(data);
    return data;
  }

最后,你不需要显式声明一个在{#await}块中使用它的承诺,你知道getPlayer() returns一个承诺,所以你可以直接使用它:

<main>
{#await getPlayer()}
    <p>Search for a Player...</p>
{:then data}
    <p>Overall Rank: {data.overallRank}</p>
{/await}
</main>

See functioning REPL