简体   繁体   中英

How to call async function to use return on global scope

I'm currently struggling with a function call, when I call the function from an if statement it does work but when I call it from outside it doesn't, my if statement only checks which button was pressed but I'm trying to remove the function from the button and just call it as soon as my app starts.

We will look at fetchJokes() inside jokeContainer.addEventListener('click', event => {

This is my current code:

const jokeContainer = document.querySelector('.joke-container');
const jokesArray = JSON.parse(localStorage.getItem("jokesData"));

// Fetch joke count from API endpoint
async function sizeJokesArray() {
  let url = 'https://api.icndb.com/jokes/count';
  let data = await (await fetch(url)).json();
  data = data.value;
  return data;
}

// use API endpoint to fetch the jokes and store it in an array
async function fetchJokes() {
  let url = `https://api.icndb.com/jokes/random/${length}`;
  let jokesData = [];
  let data = await (await fetch(url)).json();
  data = data.value;
  for (jokePosition in data) {
    jokesData.push(data[jokePosition].joke);
  }
  return localStorage.setItem("jokesData", JSON.stringify(jokesData));;
}

const jokeDispenser = (function() {
  let counter = 0; //start counter at position 0 of jokes array
  function _change(position) {
    counter += position;
  }
  return {
    nextJoke: function() {
      _change(1);
      counter %= jokesArray.length; // start from 0 if we get to the end of the array
      return jokesArray[counter];
    },
    prevJoke: function() {
      if (counter === 0) {
        counter = jokesArray.length; // place our counter at the end of the array
      }
      _change(-1);
      return jokesArray[counter];
    }
  };
})();

// pass selected joke to print on html element
function printJoke(joke) {
  document.querySelector('.joke-text p').textContent = joke;
}

sizeJokesArray().then(size => (length = size)); // Size of array in response

jokeContainer.addEventListener('click', event => {
  if (event.target.value === 'Fetch') {    
    fetchJokes(length);
  } else if (event.target.value === 'Next') {
    printJoke(jokeDispenser.prevJoke(jokesArray));
  } else if (event.target.value === 'Prev') {
    printJoke(jokeDispenser.nextJoke(jokesArray));
  }
});

And I'm trying to do something like this:

// pass selected joke to print on HTML element
function printJoke(joke) {
  document.querySelector('.joke-text p').textContent = joke;
}

sizeJokesArray().then(size => (length = size)); // Size of array in response
fetchJokes(length);

jokeContainer.addEventListener('click', event => {
  if (event.target.value === 'Next') {
    printJoke(jokeDispenser.prevJoke(jokesArray));
  } else if (event.target.value === 'Prev') {
    printJoke(jokeDispenser.nextJoke(jokesArray));
  }
});

By the way, I'm aware that currently, you can't actually iterate through the array elements using prev and next button without refreshing the page but I guess that will be another question.

Couldn't think of a better title.(edits welcomed)

Async functions are, as the name implies, asynchronous . In

sizeJokesArray().then(size => (length = size)); // Size of array in response
fetchJokes(length);

you are calling fetchJokes before length = size is executed because, as you may have guessed, sizeJokesArray is asynchronous.

But since you are already using promises the fix is straightforward:

sizeJokesArray().then(fetchJokes);

If you have not fully understood yet how promises work, maybe https://developers.google.com/web/fundamentals/getting-started/primers/promises helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM