【问题标题】:Node.js recursive calls with q framework for multiple GET requests带有 q 框架的 Node.js 递归调用,用于多个 GET 请求
【发布时间】:2016-10-31 17:18:36
【问题描述】:

在搜索 stackoverflow 和 Q 文档后,很遗憾我仍然不了解 q.ninvoke 函数。我想知道是否有人可以向我解释它是如何与我的场景一起工作的:

我正在获取 fetchXml 请求的结果,该请求最多返回 5000 个条目。我想实现一个调用自身(通过链)的方法,直到服务器不再响应任何 pagingcookie。

最后,所有结果都应该通过递归连接到递归的顶部......

var tryReexecuteForNext5000Entries = function(entitySetName, fetchXml, args){
    var deferred = q.defer();
    var response = args[0];    
    var jsonBody = args[1];
    var fetchXmlPagingCookieResponse = jsonBody["@Microsoft.Dynamics.CRM.fetchxmlpagingcookie"];

    if(!fetchXmlPagingCookieResponse){        
        deferred.resolve(args);
        return deferred.promise;
    }

    var pagingArgs = getPagingArgs(fetchXmlPagingCookieResponse);
    var pageNumber = pagingArgs[0];
    var pagingCookie = transformCookieForFetch(pagingArgs[1]);
    fetchXml = injectPagingArgsIntoFetchXml(fetchXml, pageNumber, pagingCookie);


    getWithFetchXml(entitySetName, fetchXml)        //recursion!
         .done(function(bodyValue){
             args[1].value = args[1].value.concat(jsonBody.value).concat(bodyValue);
             deferred.resolve(args);
        }
        .fail(function(error){
            deferred.reject(error);
        }));

    return deferred.promise;
}

function getWithFetchXml(entitySetName, fetchXml){
    return AuthProvider.retrieveToken()
        .then(createFetchOptions.bind(this, entitySetName, fetchXml))
        .then(addProxyToOptions)
        .then(executeRequest)
        .then(checkResponse)
        .then(tryReexecuteForNext5000Entries.bind(this, entitySetName, fetchXml))
        .then(onRequestSucceeded.bind(this, "successfully GET fetchXml against CRM"))
        .fail(onFail.bind(this, "webApiRequest.getWithFetchXml: failed to GET with fetchXml: \r\n"+fetchXml));
}

使用此设置 Q 抛出“TypeError: Cannot read property 'apply' of undefined”

应该如下工作:

  • 调用 getWithFetchXml
  • 检索 JsonObject List1 和 pagingtoken AND
  • ===调用 getWithFechXml²
  • ===检索 JsonObject List2 和 pagingToken AND
  • ======调用 getWithFetchXml³
  • ======检索 JsonObject List3 没有 pagingToken
  • ======返回列表
  • ===将 List3 附加到 List2 并返回
  • 将 List2 附加到 List1 并返回

【问题讨论】:

  • 我认为你需要精简你的代码,直到你对导致 TypeError 的原因有所了解。我们无法告诉您是什么原因造成的,但我在您的代码中看到了两个错误:(1)您使用的是concat(),但没有将结果分配给任何东西。 concat() 返回一个新数组;它不会修改原件。 (2) 您在getWithFetchXml() 的结果上调用done(),但该函数中的最后一个then()onRequestSucceeded,所以bodyValue 将是返回的任何内容(可能是undefined?)。
  • 这两个函数中的哪一个是最初调用来启动操作的?
  • 谢谢!我编辑了这个问题,也许现在更清楚了

标签: javascript node.js recursion q deferred


【解决方案1】:

这是一个愚蠢的语法错误...抱歉,我在开发 javascript 时没有设置我的 VisualStuidoCode 以获得良好的反馈。

问题是:

getWithFetchXml(entitySetName, fetchXml)        //recursion!
        .done(function(bodyValue){
             args[1].value = jsonBody.value.concat(bodyValue);
             deferred.resolve(args);
        }
        .fail(function(error){
            deferred.reject(error);
        }));

括号错误!应该是:

getWithFetchXml(entitySetName, fetchXml)        //recursion!
            .then(function(bodyValue){
                 args[1].value = jsonBody.value.concat(bodyValue);
                 deferred.resolve(args);
            })
            .fail(function(error){
                deferred.reject(error);
            });

这是我在 Node.js 中运行的递归 JavaScript 代码:

function getWithFetchXml(entitySetName, fetchXml){
    return getWithFetchXmlRecursive(entitySetName, fetchXml, null);
}

var getWithFetchXmlRecursive = function(entitySetName, fetchXml, page){
    return AuthProvider.retrieveToken()
        (...)
        .then(tryReexecuteForNext5000Entries.bind(this, entitySetName, fetchXml, page))
        .then(onRequestSucceeded.bind(this, "successfully GET fetchXml against CRM"))
        .fail(onFail.bind(this, "webApiRequest.getWithFetchXml: failed to GET with fetchXml: \r\n"+fetchXml));
}

var tryReexecuteForNext5000Entries = function(entitySetName, fetchXml, page, args){
    (...)
    var fetchXmlPagingCookieResponse = jsonBody["@Microsoft.Dynamics.CRM.fetchxmlpagingcookie"];        
    var onRecursionSucceeded = function(bodyValue){
        args[1].value = jsonBody.value.concat(bodyValue);
        deferred.resolve(args);
    }
    var onRecursionFailed = function(error){deferred.reject(error);};

    if(!fetchXmlPagingCookieResponse){        
        deferred.resolve(args);
        return deferred.promise;
    }
    (...)
    console.log("webApiRequest.tryReexecuteForNext5000Entries: there is more! starting recursive request with depth: " + (page-1));
    getWithFetchXmlRecursive(entitySetName, fetchXml, ++page)        //recursion!
        .then(onRecursionSucceeded)
        .fail(onRecursionFailed);

    return deferred.promise;
}

【讨论】:

    猜你喜欢
    • 2015-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-26
    相关资源
    最近更新 更多