简体   繁体   English

如何使递归函数正确地工作与承诺

[英]How to make a recursive function work properly with a promise

I have a recursive function that returns a promise, which I then do something based on the outcome of that promise. 我有一个递归函数,它返回一个诺言,然后我根据该诺言的结果执行一些操作。 The problem is that it is only returning one iteration of the recursive function, which is not making sense to me. 问题在于它仅返回递归函数的一个迭代,这对我来说没有意义。

I have tried to get this to work by using a setTimeout call, which works but is not good practice. 我试图通过使用setTimeout调用来使此工作正常,但这不是一个好习惯。 I have also tried desperately putting in another then after the promise to see if that would help. 我也曾尝试过在承诺之后拼命地放入另一个,看看是否有帮助。

The variable I am trying to get the correct value for is "SurveyArray". 我试图获取正确值的变量是“ SurveyArray”。 The "Survey" variable gives the correct results of three arrays. “ Survey”变量给出三个数组的正确结果。 SurveyArray should be a consolidation of those arrays into one array of 245 elements, but it is coming up with 100 elements, which is just one array worth of elements. SurveyArray应该是将这些数组合并为一个包含245个元素的数组,但是它提出了100个元素,这仅是一个元素数组。 In my code I have logged both "Survey" and "SurveyArray" to the console. 在我的代码中,我已经将“ Survey”和“ SurveyArray”都记录到了控制台。 You can see this in action in this codepen: https://codepen.io/anon/pen/JVxmKP 您可以在此代码笔中看到此操作: https ://codepen.io/anon/pen/JVxmKP

var apiToken = "h69TKYgxu46SMEXzcKkeRUXovq2jALTpHDhPUGLq"
var dataCenter = "co1"

var baseUrl = "https://cors-anywhere.herokuapp.com/https://" + 
dataCenter + ".qualtrics.com/API/v3/surveys"


function getSurveys(url) {
// Default options are marked with *
    return fetch(url, {
        method: "GET", // *GET, POST, PUT, DELETE, etc.
        mode: "cors",
        // include, *same-origin, omit
        headers: {
            "Content-Type": "application/json",
            "x-api-token": apiToken,
            "accept": "application/json"
        }
    })
    .then(response => response.json()); // parses response to JSON
}

var Surveys = []
var offset = 0;
var page = 0
var SurveyArray = []

GroupSurveys(baseUrl).then(function(){

    console.log(Surveys)
    Object.keys(Surveys).forEach(function(surveys) {

Object.keys(Surveys[surveys]. 
result.elements).forEach(function(survey) {


SurveyArray.push(Surveys[surveys].result.elements[survey].name)
    })

     console.log(SurveyArray)

})





})

function GroupSurveys(url) {
    return getSurveys(url)
        .then(data => Surveys.push(data))
        .then(function() {
            if (Surveys[page].result.nextPage) {
                offset += 100
                page += 1
                GroupSurveys(baseUrl + "?offset=" + offset)
            }

    })
    .catch(error => console.error(error)); // JSON-string from 
`response.json()` call
}

I expect the SurveyArray to have 245 elements, 100 from the first array, 100 from the second array, and 45 from the last array. 我希望SurveyArray具有245个元素,第一个数组包含100个元素,第二个数组包含100个元素,最后一个数组包含45个元素。 It is only coming up with 100 elements, which is just one array worth of data. 它只提供了100个元素,这只是一个数组的数据。

You need wrap GroupSurveys by Promise that tracks all request done: 您需要包装Promise的GroupSurveys来跟踪所有已完成的请求:

function GroupSurveys(url) {
    return new Promise(res => {
        function GroupSurveysRecursive(url) {
            getSurveys(url)
                .then(data => Surveys.push(data))
                .then(function () {
                    if (Surveys[page].result.nextPage) {
                        offset += 100;
                        page += 1;
                        GroupSurveysRecursive(baseUrl + '?offset=' + offset)
                    } else {
                        res();
                    }
                })
                .catch(error => console.error(error)); // JSON-string from `response.json()` call
        };
        GroupSurveysRecursive(url);
    })
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM