Функция await не выполняется перед переходом на следующую строку. (Асинхронное / ожидание не работает) - PullRequest
1 голос
/ 01 февраля 2020
<!DOCTYPE html>
<html>
    <head>
        <title>Async/Await</title>
    </head>
    <body>
        <button id="getData">getData</button>
    <script>
        document.getElementById("getData").addEventListener("click", getAll);
        function displayData(){
            return new Promise((res, rej)=>{
                fetch("https://jsonplaceholder.typicode.com/posts").then((res)=>{
                    return res.json();
                }).then((data)=>{
                    console.log(data);
                }).catch((err)=>{
                    rej(err);
                });
                fetch("https://jsonplaceholder.typicode.com/users").then((res)=>{
                    return res.json();
                }).then((res)=>{
                    console.log(res);
                }).catch((err)=>{
                    rej(err);
                })
                res();
            });
        }

        function getmoreData(){
            fetch("https://reqres.in/api/users/2").then((res)=>{
                return res.json();
            }).then((data)=>{
                console.log(data.data);
            }).catch((err)=>{
                console.log(err);
            });
        }

        async function getAll(){
            await displayData();
            getmoreData();
        }
    </script>
    </body>
</html>

Я хочу вызвать два API одновременно, который находится в функции отображения, и после получения этих данных я хочу вызвать другой API, который находится в функции getmoreData. Вот почему я использовал обещания и asyn c await, но когда я нажимаю кнопку, сначала выполняется getmoreData, а затем я получаю данные этих двух API, которые находятся в функции displayData. Что-то не так в моем коде, и если нет, то почему я не получаю желаемого результата.

Ответы [ 2 ]

3 голосов
/ 01 февраля 2020

Проблема в том, что вы выполняете обещание, которое вы возвращаете с displayData до поступления ответов fetch.

Чтобы исправить это, вы можете пропустить создание нового Promise и используйте Promise.all. Вот пример:

function displayData(){
    const call1 = fetch("https://jsonplaceholder.typicode.com/posts").then((res)=>{
        return res.json();
    }).then((data)=>{
        console.log(data);
        return data;
    });
    const call2 = fetch("https://jsonplaceholder.typicode.com/users").then((res)=>{
        return res.json();
    }).then((res)=>{
        console.log(res);
        return res;
    });
    return Promise.all([call1, call2]);
}

Кроме того, у вас есть повторяющийся код, который можно изменить на:

function getAndPrintData(url) {
  return fetch(url)
    .then(rsp => rsp.json())
    .then(json => {
      console.log(json);
      return json;
    });
}

const base = "https://jsonplaceholder.typicode.com/";
const urls = [`${base}posts`, `${base}users`];

function displayData() {
  return PromiseAll(urls.map(getAndPrintData));
}
0 голосов
/ 01 февраля 2020

При желании вы можете сделать вторую функцию обратным вызовом при первом разрешении:

async function getAll(){
    await displayData().then( () => getmoreData() )
}
...