Javascript承诺在recusive函数

时间:2017-07-13 18:47:31

标签: javascript ajax recursion es6-promise

我的应用程序中有一个必须执行多次分页的函数。但是在第一次之后,resolve再也不会执行了。 我错过了什么吗?

function start(){
    $.when(myrequest()).done(function(result){
         console.log(result);
    })
}

function myrequest(myurl){
    //NOTE this is just an example but the idea is the same. 
    return new Promise(function(resolve, reject){
         $.ajax({
              url: myurl,
              method: "GET",
              contentType: "application/json",
              headers:{
                   Authorization: key
              },
              success: function(response) {
                 if (response.currenturl !== response.lasturl) {
                      myurl = response.nexturl;
                      //Do stuff with data here as well to create a list. 
                      myrequest(myurl);
                      //RESOLVES JUST FINE
                      resolve("test");
                 }else{
                      //DOESN'T RESOLVE
                      resolve("test");
                 }
              },
              error: function(response){
                   reject("error");
              }
         })
    })
}

我错过了什么?任何帮助是极大的赞赏。

4 个答案:

答案 0 :(得分:3)

就像零说的那样,你必须通过在决心中返回它来传播递归的承诺。

success: function(response) {
             if (response.currenturl !== response.lasturl) {
                  myurl = response.nexturl;
                  //Do stuff with data here as well to create a list. 

                  // *heres magic
                  resolve(myrequest(myurl));

答案 1 :(得分:2)

你的myrequest(...);调用返回一个promise,并且你正在进一步执行该promise对象的监视器,所以每当该promise被解析时,返回的对象(然后/ done)处理程序将调用,但在你的递归中myrequest(myurl);的召唤,你没有使用它的东西(A promise),你正在失去这种承诺(有点泄密),所以很明显,即使这个承诺得到解决,没有人拥有对它的引用,所以他们可以执行一些事情来倾听解决。

答案 2 :(得分:1)

您没有使用myrequest的递归结果(承诺)。

例如,你可以这样做:

if (response.currenturl !== response.lasturl) {
  myurl = response.nexturl;
  //Do stuff with data here as well to create a list. 
  $.when(myrequest(myurl)).done(function (result) {
    //RESOLVES JUST FINE
    resolve("test");
  });
}

答案 3 :(得分:1)

您实际上不需要使用new Promise创建新的承诺,因为$.ajax已经返回了承诺。此外,您不需要$.when,这主要用于处理一系列承诺,但您只传递一个承诺。相反,请使用承诺的then方法。

这样的事情:

function start(startUrl){
    return myrequest(startUrl).then(function(result){
        console.log(result);
    });
}

function myrequest(myurl, collected = []){
    return $.ajax({
        url: myurl,
        method: "GET",
        contentType: "application/json",
        headers:{
           Authorization: key
        }
    }).then(function(response) {
        if (response.currenturl !== response.lasturl) {
            // add something to the partial results, 
            // e.g. the url, but could be response data:
            collected.push(myurl);
            //Do stuff with data here as well to create a list.
            //...
            // Also pass on the partial results:
            return myrequest(response.nexturl, collected); 
        } else {
            return collected; // return all the results
        }
    });
}