【问题标题】:JavaScript: Returning array from recursive functionJavaScript:从递归函数返回数组
【发布时间】:2019-04-25 05:24:17
【问题描述】:

我已经创建了一个从 api 构建一些数据的类:

const http = require("http");

class VideoService {

    constructor() {
        this.items = [];
    }

    fetchVideos(token = "") {

        const url = `https://www.example.com`;

        http.getJSON(url).then((results) => {
            results.items.forEach((item, index) => {
                const vid = item.snippet.resourceId.videoId;

                this.items.push({
                    title: item.title,
                    date: item.publishedAt
                });

                console.log(this.items.length); // here length inreases, works here
            });

            if (typeof results.nextPageToken !== "undefined") {
                return this.fetchVideos(results.nextPageToken);
            }

        });
    }

    getVideos() {
        this.fetchVideos();

        console.log(this.items.length); // this returns 0 instead of all items fetched

        return this.items;
    }

}

module.exports = VideoService;

在另一个文件中,我是这样使用的:

const videoService = require("../shared/videoService");

const videos = (new videoService()).getVideos();
console.log(videos);

最后一次console.log 调用总是返回空数组,而不是在上述类的items 属性中收集的所有数据。

谁能告诉我这里缺少什么?

【问题讨论】:

  • 是的,所以你的函数 fetchVideos() 有一个 http 调用,它将被异步处理。我建议使用 Promise 或 Observable 之类的东西。您可以在此处阅读有关 Promises 的更多信息。 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • 详细说明:对.getJSON() 的调用立即返回,收到对底层 HTTP 请求的响应之前。
  • @Pointy:谢谢,但我对 Promise 的东西相当陌生,我不明白如何修改此代码以使用 Promise。我很乐意看到答案中的修复,所以我可以接受它。谢谢
  • 您的主要问题是在递归结束时您没有返回(已解决的)承诺。
  • 也许the following answer 可以帮助您根据先前请求的结果提出请求。

标签: javascript node.js ecmascript-6


【解决方案1】:

发生这种情况是因为在您的函数fetchVideos() 中,您正在进行一个将异步处理的http 调用。你可以尝试这样处理。

fetchVideos(token = "") {

    const url = `https://www.example.com`;

    return http.getJSON(url).then((results) => {
        results.items.forEach((item, index) => {
            const vid = item.snippet.resourceId.videoId;

            this.items.push({
                title: item.title,
                date: item.publishedAt
            });

            console.log(this.items.length); // here length inreases, works here
        });

        if (typeof results.nextPageToken !== "undefined") {
            return this.fetchVideos(results.nextPageToken);
        }
        else return new Promise((resolve, reject)=>{
          resolve();
        });

    });
}

getVideos() {
    return this.fetchVideos().then(function(){
       console.log(this.items.length); // this returns 0 instead of all items fetched
    return this.items;
    });
}

我建议阅读有关 javascript 中的承诺和异步性的内容。检查此链接: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

【讨论】:

  • 这是一个好的开始,但由于在fetchVideos() 的回调中发起了进一步的 HTTP 请求这一事实,事情变得更加复杂。
  • @Pointy 不错。我以前没有注意到。
  • @LloydFrancis:它仍然无法按预期工作,console.log 没有显示任何结果。
  • fetchVideos 函数未能在递归调用链的末尾返回 Promise
猜你喜欢
  • 2022-01-02
  • 1970-01-01
  • 2012-05-29
  • 2013-08-07
  • 2020-04-08
  • 1970-01-01
  • 2015-10-23
  • 2015-04-27
相关资源
最近更新 更多