【问题标题】:Node.js, Express Routes, async and callback/building a result objectNode.js、Express Routes、异步和回调/构建结果对象
【发布时间】:2015-05-15 19:13:09
【问题描述】:

我遇到了另一堵砖墙,我无法完全掌握在这里做什么,或者至少不知道如何以正确的方式去做。我已经实现了一个异步调用,因此我可以在瀑布方法中运行多个请求,并且每个请求都依赖于另一个请求的结果。这很好,问题是,瀑布的第三步实际上需要发出多个请求。

我现在的情况如下:

async.waterfall([
    function(callback) {
        Object.find().exec(function (err, records) {
            callback(null, records);
        });
    },
    function(arg1, callback) {
        request('url' + arg1.property + '', function(err, resp, body) {
            callback(null, arg1, JSON.parse(body));
        });
    },
    function(arg1, arg2, callback) {
        var array = {newarray:[]};

        arg2.forEach(function(eachField){
            request('url' + arg2.property, function(err, resp, body) {
                array.newarray.push(JSON.parse(body));
            });
        });

        // AT THIS POINT THIS ARRAY SHOWS AS EMPTY
        console.log(array);

        callback(null, arg1, arg2, array);
    }
], function (err, result) {
    // RESULT BREAKS DUE TO FORMAT OF DIFFERENT RESPONSES
    console.log(result);
}); 

这是一种工作。它发出第一个请求,将数据发送到瀑布中的第二个函数,发出 10 个进一步的请求,等等。

首先,我推动所有内容的数组在“请求”调用之外显示为空,其次,每个请求返回的数据格式不同 - 我可以整理第二部分,但基本上我需要要了解如何提出请求,请在该请求的后面再提出 10 个(小而诚实的!)请求并将这些请求构建到一个对象中。

最后,我基本上想得到类似的结果:

{ 响应1:数据集, 响应2:数据集, 响应3:数据集 }

将来,我可能想添加或更改其中的一些,所以任何帮助都会非常有帮助!!!我要做的就是发出一些请求,用他们的 JSON 响应构建一个对象,所以在我看来,我可以用大量数据做我想做的事!

谢谢

【问题讨论】:

    标签: node.js asynchronous express request npm


    【解决方案1】:

    让我们放大第三步,因为您的其余代码似乎可以工作。问题是array.newarray.push(...) 在一个回调函数中,一旦对请求的响应进入,就会调用它。节点不会等待这种情况发生,它只是在循环中发出请求,console.logs您的数组(当时仍然是空的)然后调用开始下一步的回调。然后在稍后的某个时间点响应进来,你的回调被执行并且属性被推送到那个数组,但是到那时已经太晚了。

    所以,这里需要发生的是,我们需要等待所有请求返回,然后调用回调进行下一步。您可以为此任务使用异步,但这次使用map 操作。使用它,我们可以像这样重写步骤:

    function(arg1, arg2, callback) {
        var sendRequest = function(eachField, requestCallback) {
            //This function will be called for each element of arg2.
            request('url' + arg2.property, requestCallback);
        };
    
        async.map(arg2, sendRequest, function(err, responseArray) {
            //responseArray contains the responses to all your requests.
            callback(null, arg1, arg2, array);
        });
    }
    

    请注意,此代码仍然包含我从您的代码中接管的一些错误(例如,arg2.property 始终相同,因此您发出许多相同的请求)。

    那么这里会发生什么?我创建了一个单独的函数,它对某个字段发出实际请求。 async.map()arg2 的每个元素调用一次该函数。它一直等到每个sendRequest() 调用其回调并返回结果。然后它调用作为其第三个参数传递的函数并将所有这些结果传递给一个数组。得到结果后,您可以拨打您的async.waterfall() 的下一步。

    【讨论】:

    • 谢谢 Jasper,我真的很忙,所以一两周内无法花时间尝试上面的示例,但当我这样做时,我一定会回来投票/接受答案:)。看起来很棒,但完全有道理。
    猜你喜欢
    • 2012-07-15
    • 2017-03-20
    • 2017-06-17
    • 2021-09-10
    • 1970-01-01
    • 2012-01-02
    • 2016-02-22
    • 2018-01-14
    • 2014-10-10
    相关资源
    最近更新 更多