简体   繁体   English

我想一键调用两个函数,并确保它们一个接一个地工作

[英]i want to call two functions on one click and make sure they will work one after another

i would like to get help with a problem im trying to solve, so the problem is that i have to call two APIs url.我想就我试图解决的问题寻求帮助,所以问题是我必须调用两个 API url。 the second depend on the first (in the first fetch im getting some basic info , including ids, in the second fetch i want to fetch data based on the ids from the first fetching).第二个依赖于第一个(在第一次获取中,我获取了一些基本信息,包括 ID,在第二次获取中,我想根据第一次获取的 ID 获取数据)。 i always getting this error: Uncaught TypeError: Cannot read property 'length' of undefined probably my approach is not correct.我总是收到此错误: Uncaught TypeError: Cannot read property 'length' of undefined可能我的方法不正确。 i tried few things like putting the second function inside the first function, i tried to do it without async, its only working when i have two different buttons.我尝试了一些事情,例如将第二个函数放在第一个函数中,我尝试在没有异步的情况下执行此操作,它仅在我有两个不同的按钮时才有效。 i guess the async is causing this problem.(its trying to get the length before the respond) please help me with this one.我猜是异步导致了这个问题。(它试图在响应之前获得长度)请帮我解决这个问题。 i would love to get some insight about approach or any way to solve it.我很想了解一些有关方法或解决方法的见解。 thanks in advance.提前致谢。 this is the problematic code这是有问题的代码

//recipies by ingredients array
var displayData = [];
//full recipies array
var displayRecipes = [];

document.getElementById("search").addEventListener("click", function () {
  var l = document.getElementsByClassName("ingInput").length
  var ing = document.getElementById('id').value
  var ing1 = ''
  //getting all the values from the inputs so i can search it in the api url
  for(var i = 1; i<l ;i++){
    ing1 += ',' + document.getElementsByClassName("ingInput")[i].value 
  }
  //async get request for the api url 
 async function postData(url = '') {
    const response = await fetch(url, {
      method: 'GET', // *GET, POST, PUT, DELETE, etc.
      headers: {
        'Content-Type': 'application/json'
        // 'Content-Type': 'application/x-www-form-urlencoded',
      },

    });
    return response.json(); // parses JSON response into native JavaScript objects
  }
  //the api url with the inputs values for searching by ingredeints
  postData('https://api.spoonacular.com/recipes/findByIngredients?ingredients='+ ing + ing1 + '&number=10&apiKey=API_KEY')
    .then((data) => {
      displayData.push(data); // JSON data parsed by `response.json()` call
      console.log('done')
    });

})

//second func
document.getElementById("search").addEventListener("click", function () {
//trying to get data from this array, here i have error.
  var l = displayData[0].length
  var ids = []
  for(var i = 0; i<l ;i++){
    ids.push(displayData[0][i].id) 
  }

  async function postData(url = '') {
    // Default options are marked with *
    const response = await fetch(url, {
      method: 'GET', // *GET, POST, PUT, DELETE, etc.
      headers: {
        'Content-Type': 'application/json'
        // 'Content-Type': 'application/x-www-form-urlencoded',
      },

    });
    return await response.json(); // parses JSON response into native JavaScript objects
  }

  postData('https://api.spoonacular.com/recipes/informationBulk?ids='+ids.toString()+'&apiKey=API_KEY')
    .then((data) => {
      displayRecipes.push(data); // JSON data parsed by `response.json()` call
      console.log(displayRecipes)
    });

})```

How about you make the second fetch only if you have data from the first?仅当您有第一次获取的数据时,才进行第二次获取怎么样? This way, when no data exists, the button fetches initial data.这样,当不存在数据时,按钮获取初始数据。 If data already exists, it fetches the additional info.如果数据已经存在,它会获取附加信息。 So you have a single listener:所以你只有一个监听器:

 document.getElementById( "search" ).addEventListener( "click", function () {
    if ( displayData.length === 0 ) {
        // Call first function 
    } else {
        // Call second function
    }
 })

i found a solution to my problem, im not sure if its the best way to do it, but its working fine for me.我找到了解决我的问题的方法,我不确定它是否是最好的方法,但它对我来说很好用。 so the dom looks like this: (i added onclick to the search button)所以dom看起来像这样:(我在搜索按钮上添加了onclick)

<div id="container">
        <!-- first input for the first ingrediant you can search -->
        <input type="text" class="ingInput" id="id" placeholder="ingrediant" onfocus="auto(this)">
    </div>
    <!-- search button, first bring the recipies based on ingredient, then the full recipies based on ids from the first fetch data -->
    <button  id="search" onclick="asyncCall()">Search</button>

    <!-- add new input for more ingrediant -->
    <button id="add" onclick="add()">Add</button>

    <!-- display the element i have created from the data i have -->
    <div id="display">

    </div>
    <!-- for jquery pagination -->
<button id="btn_prev">Prev</button>
<button id="btn_next">Next</button>
page: <span id="page"></span>

and the javascript for getting the data (first from the first api link then from the second api link):以及用于获取数据的 javascript(首先从第一个 api 链接然后从第二个 api 链接):

//recipies by ingredients array
var displayData = [];

//full recipies array
var displayRecipes = [];

async function search(){

  var l = document.getElementsByClassName("ingInput").length
  var ing = document.getElementById('id').value
  var ing1 = ''
  //getting all the values from the inputs so i can search it in the api url
  for(var i = 1; i<l ;i++){
    ing1 += ',' + document.getElementsByClassName("ingInput")[i].value 
  }

  //the api url with the inputs values for searching by ingredeints
 await fetch('https://api.spoonacular.com/recipes/findByIngredients?ingredients='+ ing + ing1 + '&number=10&apiKey=API_KEY', {
    method: 'GET', // *GET, POST, PUT, DELETE, etc.
    headers: {
      'Content-Type': 'application/json'
      // 'Content-Type': 'application/x-www-form-urlencoded',
    }
  }).then(res => res.json())
    .then((data) => {
      displayData.push(data); // JSON data parsed by `response.json()` call
      console.log('done')
    });   
}

async function getRecipes(){
  var l = displayData[0].length
  var ids = []
  for(var i = 0; i<l ;i++){
    ids.push(displayData[0][i].id) 
  }
  await fetch('https://api.spoonacular.com/recipes/informationBulk?ids='+ids.toString()+'&apiKey=API_KEY',{
      method: 'GET', // *GET, POST, PUT, DELETE, etc.
      headers: {
        'Content-Type': 'application/json'
        // 'Content-Type': 'application/x-www-form-urlencoded',
      }
    })
    .then(res => res.json())
    .then((data) => {
      displayRecipes.push(data); // JSON data parsed by `response.json()` call
      console.log(displayRecipes)
    });   
}

async function asyncCall() {
  console.log('calling');
  const resultSearch = await search();
  console.log('done await search');

  console.log('calling2');
  const resultRecipies = await getRecipes();
  console.log('done await recipes');

}```

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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