【问题标题】:Working with async/await and then() how to save results in array使用 async/await 和 then() 如何将结果保存在数组中
【发布时间】:2018-02-03 04:52:54
【问题描述】:

我正在练习我的 javascript 技能,做一个从 API 收集笑话并显示它们的笑话机器,我的问题是目前,我正在使用 .then() 这很好,但我想知道如何获得我的结果是一个不需要像fetchJokes().then(jokes => console.log(jokes)); 那样等待.then() 的数组

我曾经有一个像这样导航数组的函数:

let counter = 0;
let jokes = [joke1, joke2, joke3, joke4];

function nextJoke(jokes) {
  counter++;
  counter %= jokes.length; // start from 0 if we get to the end of the array
  return jokes[counter]; // give us back the actual item
}

这就是在从 API 获取之前使用它的方式。

这是我当前的代码:

const url = "https://api.icndb.com/jokes/random/5";
const fetchButton = document.querySelector("button[type=button][value=Fetch]");

async function fetchJokes() {
  let jokes = [];
  let data = await (await fetch(url)).json();
  for (let i = 0; i < 5; i++) {
    jokes[i] = data.value[i].joke;
  }
  return jokes;
}

fetchButton.addEventListener("click", () => {
  fetchJokes().then(jokes => console.log(jokes));
});
&lt;button type="button" value="Fetch"&gt;Fetch Jokes&lt;/button&gt;

所以我已经弄清楚如何使用按钮和所有爵士乐,只是寻求有关如何传递我从fetchJokes() 接收的对象并将其存储在数组中的帮助。

【问题讨论】:

  • 嗯...你似乎已经这样做了。
  • 是的,您已经从异步方法返回了一个数组。
  • 你不能(不应该)像以前那样将它存储在一个全局数组中。当请求仍在加载时调用nextJoke 函数时,您希望它做什么? A)它必须等待自己 - 所以将数组的承诺存储在全局变量中 B)在承诺履行之前它不会被调用 - 所以只需在 then 处理程序中声明它
  • @Bergi 我想要实现的是获取我的 jokes 数组并在我的代码周围使用它,而不必每次都在每个不同的函数上获取它,读到你提到我应该不将其存储在全局数组中,所以也许我的方法是错误的?另一个例子是,如果我尝试在fetchJokes() 函数之外使用console.log(jokes)
  • @Nava 您不必每次都获取它,只要在任何地方等待相同的获取就足够了-您可以store the promise itself in a global variable。另一种方法是将所有想要使用jokes 的代码包装在一个大的then 回调中。

标签: javascript arrays object async-await


【解决方案1】:

我不确定我是否理解这个问题...如果您想从异步 api 中获取并且不必使用 .then 或必须等待,那么这是不可能的。

根据我对这个问题的理解,如果你不想每次都使用 .then,只在数组为空时获取(只获取一次):

const url = "https://api.icndb.com/jokes/random/5";
const fetchButton = document.querySelector("button[type=button]
[value=Fetch]");
let arr = []
let counter = 0;
async function fetchJokes() {
    let data = await (await fetch(url)).json();
    for (let i = 0; i < 5; i++) {
        arr[i] = data.value[i].joke;
    }
}

function nextJoke(jokes) {
    const item = jokes[counter]
    counter++;
    if (counter >=jokes.length){
        counter %= jokes.length;
    }// start from 0 if we get to the end of the array
    return item; // give us back the actual item
 }
fetchButton.addEventListener("click", () => {
    if (arr.length == 0){
        fetchJokes()
        .then(()=>console.log(nextJoke(arr)))
    }else{
        console.log(nextJoke(arr))
    }
  });

DEMO codepen

有很多方法可以做到这一点。我建议更多地研究Javascript Promises

【讨论】:

    【解决方案2】:

    您可以使用fetch() 来检索网址的数据。然后你必须用.then((resp) =&gt; resp.json())把它转换成json。

    之后,您可以将数据存储在 jokes 数组中。

    const url = "https://api.icndb.com/jokes/random/5";
    const fetchButton = document.querySelector("button[type=button][value=Fetch]");
    const nextButton = document.querySelector("button[type=button][value=Next]");
    const display = document.getElementById("display");
    let counter = 0;
    let jokes = [];
    
    nextButton.style.visibility = 'hidden'; //Hide next button
    
    fetchButton.addEventListener("click", () => {
      fetch(url).then((resp) => resp.json()) // Transform the data into json
        .then(data => (jokes = data.value, //Set the array of jokes
                      fetchButton.style.visibility = 'hidden', //Hide fetch button
                      nextButton.style.visibility = 'visible')); //Show next button
    });
    
    nextButton.addEventListener("click", () => {
      //Show next joke
      display.innerHTML = jokes[counter++ % jokes.length].id + " : " + jokes[counter++ % jokes.length].joke;
    });
    <button type="button" value="Fetch">Fetch Jokes</button>
    <button type="button" value="Next">Next joke</button>
    <p id="display"></p>

    【讨论】:

    • 这实际上完成了我想要实现的目标,但正如其他 cmets 中提到的那样,我认为我的疑问在于 jokes 的全球范围,或者缺乏它。
    【解决方案3】:

    这对我有用,而无需修改问题中 sn-p 的主要目的。

    let counter = 0;
    const url = "https://api.icndb.com/jokes/random/5";
    const fetchButton = document.querySelector("button[type=button][value=Fetch]");
    
    async function fetchJokes() {
      let jokes = [];
      let data = await (await fetch(url)).json();
      for (let i = 0; i < 5; i++) {
        jokes[i] = data.value[i].joke;
      }
      return jokes;
    }
    
    fetchButton.addEventListener("click", () => {
      fetchJokes().then(data => (jokes = data)).then(data => console.log(data));
    });
    &lt;button type="button" value="Fetch"&gt;Fetch Jokes&lt;/button&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-27
      • 2022-09-30
      • 2021-04-10
      • 2019-08-17
      • 1970-01-01
      • 2022-01-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多