如何同时调用两个api?

时间:2019-07-10 00:00:08

标签: javascript html api

我有两种不同的API,一种用于视频注释,一种用于用户名,现在我需要从注释API中查找具有用户ID的名称。我使用此代码。

function loadVideoCommentsById(id) {
        let output = '';
         fetch('https:///comments')
            .then(response => response.json())
            .then(function (json) {
                json.forEach(function (comment) {
                    if (comment.videoId == id) {
                        const username =  fetch('/users/'+comment.userId)
                            .then(response => response.json())
                            .then(function (json) {
                                return json.name;
                            });

                        output += `
                            <li>
                                <div class="Uid">
                                    <span>` + username + `</span> 
                                </div>
                                <div class="commentText">
                                    <p class="">${comment.body}</p>
                                    <span class="date sub-text">${comment.date}</span>

                                </div>
                            </li>
            `

                    }

                    document.querySelector('#result').innerHTML = output;

                })

            });


    }

当我将'json.name'置于警报中时,它将打印用户名,但是当我在其网站上看到运行用户名'+ username +'时: 它打印:[object Promise] 我现在应该怎么办?我是一个初学者,这是我找到用户名的唯一方法。 谢谢

2 个答案:

答案 0 :(得分:2)

一个问题是你在做

const username =  fetch ....

因此,用户名将是一个Promise,它是一个对象,这就是为什么“它打印:[object Promise]”

由于您正在处理forEach内部的多个(异步)请求,因此您可能需要使用Promise.all

您还可以使用.filter过滤所需的“评论”,并使用.map获取Promise.all等待的Promises数组

这里的代码应该起作用

function loadVideoCommentsById(id) {
     return fetch('https:///comments')
    .then(response => response.json())
    .then(json => 
        Promise.all(
            // filter only the comments that match `id`
            json.filter(comment => comment.videoID == id)
            // get the username for each comment
            .map(comment => fetch('/users/'+comment.userId)
                .then(response => response.json())
                .then(json => ({username: json.name, comment}))
            )
        )
    )
    // data will be an array like [{username, comment}, {username, comment} ...]
    .then(data => data.map(({username, comment}) => `
        <li>
            <div class="Uid">
                <span>${username}</span> 
            </div>
            <div class="commentText">
                <p class="">${comment.body}</p>
                <span class="date sub-text">${comment.date}</span>
            </div>
        </li>
        `
    ).join(''))
    .then(output => document.querySelector('#result').innerHTML = output);
}

异步/等待版本

async function loadVideoCommentsById(id) {
     let res = await fetch('https:///comments');
     let json = await res.json();
     let filtered = json.filter(comment => comment.videoID == id);
     let output = '';
     for (let i = 0; i < filtered.length; i++) {
         let comment = filtered[i];
         let res2 = await fetch('/users/'+comment.userId);
         let json2 = await res2.json();
         let username = json2.name;
         output += `
            <li>
                <div class="Uid">
                    <span>${username}</span> 
                </div>
                <div class="commentText">
                    <p class="">${comment.body}</p>
                    <span class="date sub-text">${comment.date}</span>
                </div>
            </li>
        `;
     }
    document.querySelector('#result').innerHTML = output;
}

答案 1 :(得分:0)

fetch()会返回一个承诺,您不能仅仅将其兑现。相反,您需要做的是将所有代码放在第二次fetch()调用之后的.then()回调中。

function loadVideoCommentsById(id) {
  fetch('https:///comments')
    .then(response => response.json())
    .then(comments => {
      comments
        .filter(c => c.videoId == id)
        .forEach(comment => {
          fetch('users/' + comment.userId)
            .then(response => response.json())
            .then(user => {
              const html = `
                <li>
                  <div class="Uid">
                    <span>${user.name}</span>
                  </div>
                  <div class="commentText">
                    <p>${comment.body}</p>
                    <span class="date sub-text">${comment.date}</span>
                  </div>
                </li>`;
              document.querySelector('#result').innerHTML += html;
            });
        });
    });
}

可以选择使用Promise.all()作为其他答案,以等待所有注释被提取。