承诺返回数据“ <pending>”

时间:2018-11-23 20:17:21

标签: javascript node.js asynchronous async-await

我从YouTube上获取的数据是使用nodejs的-

    [ { title:
         'Dil  Zaffran Video Song | Rahat Fateh Ali Khan |  Ravi Shankar |  Kamal Chandra | Shivin | Palak',
        id: 'vChX3XZXqN4',
        view: '28652353' },
      { title:
         'Full Video: Akh Lad Jaave | Loveyatri | Aayush S|Warina H |Badshah, Tanishk Bagchi,Jubin N, ,Asees K',
        id: 'e_vl5aFXB4Q',
        view: '17328447' 
}]

现在我要为每个视频搜索5个相关视频

我的api

getVids(videosID)
        .then(result => {
            console.log(result)  //this is the data which I showed above
            result.sort((a,b) => b.view - a.view);
            return result;
        })
        .then(result => {

            return result.map(function(el) {
                // console.log(el);
                let o = Object.assign({}, el);

                o.relatedVideos = relatedVideos(el.id); //function is called below
                return o;
            });
        })
        .then(result => {
            console.log(result);
        })
        .catch(err => {
            console.log(err)
        })

下面是5个相关视频的api

function relatedVideos(videoId) {

    return new Promise((resolve, reject) => {
        let urls = 'https://www.googleapis.com/youtube/v3/search?relatedToVideoId=' + videoId + '&key=' + API_KEY + '&part=snippet&type=video';
        request(urls, (err, result) => {
            const data = JSON.parse(result.body);
            const relatedVideos = [];
            data.items.forEach(related => {
                relatedVideos.push({
                    title: related.snippet.title
                });
                if(relatedVideos.length === 5){
                    resolve(relatedVideos);
                }
            });
        });
    });
}

它给出了类似的输出

    [ { title:
         'Dil  Zaffran Video Song | Rahat Fateh Ali Khan |  Ravi Shankar |  Kamal Chandra | Shivin | Palak',
        id: 'vChX3XZXqN4',
        view: '28655496',
        relatedVideos: Promise { <pending> } },
      { title:
         'Full Video: Akh Lad Jaave | Loveyatri | Aayush S|Warina H |Badshah, Tanishk Bagchi,Jubin N, ,Asees K',
        id: 'e_vl5aFXB4Q',
        view: '17334681',
        relatedVideos: Promise { <pending> }
 }]

如何解决此pending问题或如何等待以获取完整数据。

2 个答案:

答案 0 :(得分:2)

发生这种情况是因为将relatedVideos()返回的承诺分配给属性relatedVideos,而您实际上从未等待其解决。您需要先等待所有的诺言,然后再继续,Promise.all()最容易做到。让我们关注代码的这一部分:

        return result.map(function(el) {
            // console.log(el);
            let o = Object.assign({}, el);

            o.relatedVideos = relatedVideos(el.id); //function is called below
            return o;
        });

您需要做的是在将每个promise分配给对象之前,等待每个promise的解析,以便获得其已解析的值。然后,您还需要创建在所有这些承诺都解决之前不会解决的承诺。这就是Promise.all()的目的。将上面提到的代码更改为此:

        return Promise.all(result.map(function(el) {
            // console.log(el);
            let o = Object.assign({}, el);

            return relatedVideos(el.id)
                .then(function(relatedVideo) {
                    o.relatedVideos = relatedVideo;
                    return o;
                });
        }));

请注意,映射到Promise.all()的所有promise必须解析,以便链可以继续下一个then。如果这些承诺之一甚至拒绝或根本没有解决,它将永远不会继续。您需要在resolve()函数中进行relatedVideos()调用的条件。这意味着在某些情况下,诺言可能永远无法解决。您应该始终兑现或拒绝诺言,也许resolve(null)适合您的情况。

答案 1 :(得分:1)

这种情况发生在尚未解决承诺的情况下,因此未调用您的resolve函数。在没有以下条件的情况下进行测试可能是一个好主意。

if(relatedVideos.length === 5){
    resolve(relatedVideos);
}