简体   繁体   中英

Chaining async functions doesn't work correctly

I'm trying to chain two async functions but it seems that the second one is being executed before the first one. Here is my code

function performAction(e) {
const ZIP = document.getElementById('zip').value;
const fellings = document.getElementById('feelings').value;
console.log(`${baseURL}${ZIP},us&appid=${key}`);
getWeather(baseURL, ZIP, key,).then((data) => {
    postData('/addweather', {temperature: data.main.temp ,date:newDate, userResponse: fellings })
}).then(
    updateUI()
)}

and This is getWeather()

const getWeather = async(baseURL, ZIP, key) => {
let URL = `${baseURL}${ZIP}&appid=${key}`;
const res = await fetch(URL)
try{
    const data = await res.json();
    return data;
}catch(error){
    console.log("error", error);
}}

and this is postData() which is supposed to execute after the getWeather function is excuted but it isn't.

const postData = async ( url = '', data = {}) => {
console.log(`This is what we fetch ${data.temperature}`);
console.log(`This is what we fetch ${data.date}`);
console.log(`This is what we fetch ${data.userResponse}`);
  const response = await fetch(url, {
  method: 'POST', 
  credentials: 'same-origin',
  headers: {
      'Content-Type': 'application/json',
  },
 // Body data type must match "Content-Type" header        
  body: JSON.stringify(data), 
});
try {
    const newData = await response.json();
    console.log(`This is the new Data ${newData.temperature}`);
    return newData;
}catch(error){
  console.log("error", error);
}}

and this is updateUI()

const updateUI = async () => {
const request = await fetch('/getweather');
try{
  const allData = await request.json();
  console.log('Get request');
        document.getElementById('date').innerHTML = allData.date;
        document.getElementById('temp').innerHTML = allData.temperature;
        document.getElementById('content').innerHTML = allData.userResponse;
}catch(error){
  console.log("error", error);
}}

What happens is that the UI gets updated first so it gets the value of undefined for the first time, and when I reload the page and enter new data the UI get's updated with the data from last time.

You need to return the promise returned from postData :

getWeather(baseURL, ZIP, key,).then((data) => {
   return postData('/addweather', {temperature: data.main.temp ,date:newDate, userResponse: fellings })
}).then(() => {
   return updateUI()
})

Another way you could write this is like this:

async function run() {
   await getWeather(baseURL, ZIP, key)
   await postData('/addweather', {temperature: data.main.temp ,date:newDate, userResponse: fellings })
   await updateUI()
}

your postData() is also an async function. Therefore you have to await this aswell:

getWeather(baseURL, ZIP, key,).then(async (data) => {
    await postData('/addweather', {temperature: data.main.temp ,date:newDate, userResponse: fellings })
}).then(
    updateUI()
)}

I didn't have done javascript in a while, but i guess it is more clear in this way:

const performAction = async (e) => {
const ZIP = document.getElementById('zip').value;
const fellings = document.getElementById('feelings').value;
console.log(`${baseURL}${ZIP},us&appid=${key}`);
try{
const data = await getWeather(baseURL, ZIP, key,);
const postData= await postData('/addweather', {temperature: data.main.temp ,date:newDate, userResponse: fellings });
} catch(e) {
console.log(e)
} finally {
    updateUI();
}

Also you dont have to await the parsing of the json and the try catch should contain your request:

const postData = async ( url = '', data = {}) => {
console.log(`This is what we fetch ${data.temperature}`);
console.log(`This is what we fetch ${data.date}`);
console.log(`This is what we fetch ${data.userResponse}`);
try {
  const response = await fetch(url, {
  method: 'POST', 
  credentials: 'same-origin',
  headers: {
      'Content-Type': 'application/json',
  },
 // Body data type must match "Content-Type" header        
  body: JSON.stringify(data), 
});

    const newData = response.json();
    console.log(`This is the new Data ${newData.temperature}`);
    return newData;
}catch(error){
  console.log("error", error);
}}

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