【问题标题】:Chaining unknown number promises in a recursive function在递归函数中链接未知数的承诺
【发布时间】:2020-05-30 23:59:32
【问题描述】:

我正在尝试找到进行此服务调用的最佳方法,将所有数据保留在一个对象中。该调用返回一个具有 next_page_url 属性的对象。如果有 next_page_url 该函数应该保持链接。由于在下一次调用解决之前我不知道 url 是什么,所以我需要按顺序调用它们并按顺序解析它们。我也在收集每次通话的数据。我一直无法弄清楚应该是什么结构 到目前为止我有什么

getDataFromAllPages = (url) => {
     waniKaniAxios.get(url).then(object => {
         if(object.data.pages.next_url){
             return this.getDataFromAllPages(object.data.pages.next_url.replace(waniKaniAxios.defaults.baseURL, ''));
         }
     });
 }

 getWanikaniData = () => {
     this.getDataFromAllPages('/subjects?types=vocabulary').then(result => {
         console.log(result);
     });
 }

【问题讨论】:

    标签: javascript reactjs recursion promise


    【解决方案1】:

    将 wanikaniaxios.get 抽象到另一个函数中,使递归更清晰。

    这是我的格式错误的代码(不知道SF编辑器是如何工作的),如果您有任何问题,请随时提出。编码愉快。

    getWanikaniData = () => {
      this.getDataFromAllPages("/subjects?types=vocabulary")
        .then((result) => {
          console.log(result);
        })
        .catch((err) => {
          console.log(err); // always put a .catch when you're using prmomises.
        });
    };
    
    getDataFromAllPages = async (url) => {
      // using async await;
    
      try {
        let arr = []; // i am assuming you'll improve upon what data structure you might want to return. Linked list seems best to me.
    
        const object = await waniKaniAxios.get(url);
    
        if (object.data.pages.next_url) {
          const laterData = await this.getDataFromAllPages(
            object.data.pages.next_url.replace(waniKaniAxios.defaults.baseURL, "")
          );
          arr = [...arr, ...laterData];
        } else {
          arr = [...arr, object];
        }
    
        Promise.resolve(arr);
      } catch (err) {
        Promise.reject(new Error(`Oops new wanikani error, ${err}`));
      }
    };
    

    最终更新

    使用下面的部分答案,我设法让它工作。不得不部分放弃递归方面,因为我不知道如何将承诺解析为数据

    这是我想出的最终解决方案

    getDataFromAllPages = async (url) => {
      let results = {};
      try {
        //getting intial data
        const initialData = await waniKaniAxios.get(url);
        //using the intial data and mapping out the levels then saving it into results object
        results = this.mapOutLevels(initialData.data, results);
        //get the next page url
        let nextPageUrl = initialData.data.pages.next_url;
        //while there is a next page url keep calling the service and adding it to the results object
        while (nextPageUrl) {
          const laterData = await waniKaniAxios.get(nextPageUrl);
          nextPageUrl = laterData.data.pages.next_url;
          results = this.mapOutLevels(laterData.data, results);
        }
      } catch (err) {
        Promise.reject(new Error(`Opps new wanikani error, ${err}`));
      }
      return Promise.resolve(results);
    };
    
    getWanikaniData = () => {
      this.getDataFromAllPages("/subjects?types=vocabulary")
        .then((result) => {
          console.log(result);
        })
        .catch((err) => {
          console.log(err);
        });
    };
    

    【讨论】:

    • 非常好,我敢打赌,如果您重构代码,您会自己找到解决方案(或将重构的代码发回此处)。我最近了解到这个函数应该尽可能地愚蠢,以便可以单独测试它们。如果您想编写高质量的代码,请阅读单一责任主体和 DRY。
    • 作为评论可能比作为答案更好。
    • 我认为我的困惑来自于我没有完全理解 Promise,然后尝试将其实现为递归函数。我不明白承诺是如何发挥作用的
    • 我已经编辑了我的答案@BabyCoder,请查看。
    • laterData 似乎由于某种原因返回 null。在调用链结束后,最后一个被保存到 laterData 但之前的所有其他调用都返回 null
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-01
    • 2017-12-18
    • 1970-01-01
    • 1970-01-01
    • 2019-05-25
    • 2015-09-05
    • 2014-06-30
    相关资源
    最近更新 更多