Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在循环完成nodejs请求之前执行回调_Javascript_Arrays_Node.js_Request_Lodash - Fatal编程技术网

Javascript 在循环完成nodejs请求之前执行回调

Javascript 在循环完成nodejs请求之前执行回调,javascript,arrays,node.js,request,lodash,Javascript,Arrays,Node.js,Request,Lodash,我正在与API通信,以获取ID数组的信息。因此,数组中的每个id都需要一个对api的请求,如果响应符合逻辑,我想从响应中构建一个数据数组。但是,正在处理请求的my函数上的回调是在构建新数组之前执行的。在处理对api的大量调用时,我经常遇到这个问题。我如何修复这个特定的示例,以及将来解决这个问题的最佳方法是什么 var request = require('request'); var _ = require('lodash'); var siteLayouts = [1550, 1552, 1

我正在与API通信,以获取ID数组的信息。因此,数组中的每个id都需要一个对api的请求,如果响应符合逻辑,我想从响应中构建一个数据数组。但是,正在处理请求的my函数上的回调是在构建新数组之前执行的。在处理对api的大量调用时,我经常遇到这个问题。我如何修复这个特定的示例,以及将来解决这个问题的最佳方法是什么

var request = require('request');
var _ = require('lodash');

var siteLayouts = [1550, 1552, 1554, 1556, 1558, 1560, 1562, 1564, 1566, 1568, 1570, 1572, 1574, 1730, 1734, 1736, 1738, 1740, 1896, 1898, 1900, 1902, 1904, 1906, 1908, 1910, 1914, 1922, 1924, 1926, 1928, 1930, 1932, 1934, 1936, 1938, 1940, 1942, 1944, 1946, 1948, 1950, 1952, 1954, 1956, 1958, 1960, 1962, 1964, 1966, 1968, 1970, 1972, 1974, 1976, 1978, 1980, 1984, 1986, 1988, 1990, 1992, 1994, 1996, 1998, 2000, 2002, 2004, 2006, 2008, 2010, 2012, 2014, 2016, 2020, 2022, 2030, 2032, 2034, 2036, 2038, 2040, 2042, 2044, 2046, 2048, 2052, 2054, 2056, 2060, 2062, 2064, 2066, 2068, 2070, 2072, 2122, 2124, 2148, 2154, 2156, 2270, 2272, 2274, 2374, 2418, 2688, 2692, 2968, 3756, 4094, 5122, 5524, 7326, 7494, 8704, 8886, 9226, 9232, 9234, 9236, 9238, 9830, 9836, 10052, 10054, 10056, 10999, 11083, 11085, 11429, 11513, 17279, 20397, 22285, 22287, 22289, 22291, 22293, 22295, 22807, 22809, 22811, 22813, 22815];

function getLayoutModules(siteLayouts, callback) {
    var matchedModules = [];
    for (var i = 0; i < siteLayouts.length; i++) {
        request('http://PRIVATE-API-URL/layout/' + siteLayouts[i], function(err, res, body) {
            if (!err && res.statusCode == 200) {
                var layoutModules = JSON.parse(body);
                var match = _.filter(layoutModules, {
                    'dtoLayoutModule': {
                        'ModuleName': 'Featured Content'
                    }
                });
                if (match.length > 0 && match[0].dtoLayoutModule) {
                    //console.log(match[0].dtoLayoutModule);
                    matchedModules.push(match[0].dtoLayoutModule);
                    console.log(matchedModules.length)
                }
            }
        });
    }
    callback(matchedModules);
}

getLayoutModules(siteLayouts, function(matchedModules) {
    console.log(matchedModules);
});
var request=require('request');
var=要求('lodash');
var站点布局=[1550, 1552, 1554, 1556, 1558, 1560, 1562, 1564, 1566, 1568, 1570, 1572, 1574, 1730, 1734, 1736, 1738, 1740, 1896, 1898, 1900, 1902, 1904, 1906, 1908, 1910, 1914, 1922, 1924, 1926, 1928, 1930, 1932, 1934, 1936, 1938, 1940, 1942, 1944, 1946, 1948, 1950, 1952, 1954, 1956, 1958, 1960, 1962, 1964, 1966, 1968, 1970, 1972, 1974, 1976, 1978, 1980, 1984, 1986, 1988, 1990, 1992, 1994, 1996, 1998, 2000, 2002, 2004, 2006, 2008, 2010, 2012, 2014, 2016, 2020, 2022, 2030, 2032, 2034, 2036, 2038, 2040, 2042, 2044, 2046, 2048, 2052, 2054, 2056, 2060, 2062, 2064, 2066, 2068, 2070, 2072, 2122, 2124, 2148, 2154, 2156, 2270, 2272, 2274, 2374, 2418, 2688, 2692, 2968, 3756, 4094, 5122, 5524, 7326, 7494, 8704, 8886, 9226, 9232, 9234, 9236, 9238, 9830, 9836, 10052, 10054, 10056, 10999, 11083, 11085, 11429, 11513, 17279, 20397, 22285, 22287, 22289, 22291, 22293, 22295, 22807, 22809, 22811, 22813, 22815];
函数getLayoutModules(站点布局、回调){
var matchedModules=[];
对于(var i=0;i0&&match[0].dtoLayoutModule){
//console.log(匹配[0].dtoLayoutModule);
matchedModules.push(匹配[0].dtoLayoutModule);
console.log(matchedModules.length)
}
}
});
}
回调(匹配的模块);
}
GetLayoutModule(站点布局、函数(匹配模块){
console.log(匹配的模块);
});
我已经验证了数据是通过console.log length添加到最终数组中的,但是我首先看到callback console.log,然后是长度。另外,这里还有一个使用u.filter筛选后的请求响应体示例

[{
    RequestStatus: {
        StatusCode: '200',
        StatusTxt: 'Successful request.',
        Result: 'Successful request.',
        ValidationErrors: null
    },
    dtoLayoutModule: {
        Id: 116013,
        LayoutId: 10999,
        LayoutName: 'layout name',
        ModuleId: 7,
        ModuleName: 'Featured Content',
        DisplayName: 'name to display',
        Position: 4,
        Config: '<config><item name="layout" value="primary" /></config>',
        MaxContentCount: 4,
        CanInherit: false,
        IsInheritable: false,
        IsStaticModule: false
    }
}]
[{
请求状态:{
状态代码:“200”,
StatusTxt:“请求成功”,
结果:“请求成功。”,
验证错误:null
},
DTOLayout模块:{
身份证号码:116013,
LayoutId:10999,
LayoutName:“布局名称”,
模块ID:7,
ModuleName:“特色内容”,
DisplayName:'要显示的名称',
职位:4,
配置:“”,
MaxContentCount:4,
卡尼赫特:错,
IsInheritable:错误,
IsStaticModule:false
}
}]

for
循环不能像您希望的那样与异步代码一起工作,因为它们仅用于同步代码。使用
async.map
处理每个ID的异步请求。这将获取您的ID数组,对每个ID执行异步请求,并返回一个响应数组,然后您可以使用h常规
数组.prototype.filter
在最终将
匹配的模块
传递给回调之前。

您遇到的问题是您在同步思考,并且在异步工作。您在循环中启动请求,并在循环后立即调用回调。但您无法保证所有calls将在您调用回调方法时被处理。事实上,相反的情况是可以保证的。您需要的是一种只有在处理完所有请求后才能调用回调的方法

我认为你应该考虑使用承诺。承诺是EcMASCRIPT6的一部分,并且今天通过各种库被密集地使用。最有名的一个(据我所知)是Q,但是还有其他的。< /P> promise模式尝试(并且做得很好)消除所谓的“回调地狱”

以下是该模式的一个示例:

asyncCall()
  .then(function(data1){
     // do something...
     return anotherAsyncCall();
   })
   .then(function(data2){
     // do something...  
     return oneMoreAsyncCall();    
   })
   .then(function(data3){
      // the third and final async response
   })
   .fail(function(err) {
      // handle any error resulting from any of the above calls    
   })
   .done();
这个例子取自一篇名为Promises的文章,这是一种处理异步JavaScript的替代方法


在您的特定情况下,一种方法是收集承诺(每个承诺都是为每个请求创建的)进入一个承诺数组,然后使用Q.all方法。当所有承诺都得到解决时,该承诺就会得到解决。

谢谢@PeterLyons。我一直试图避免使用异步库,因为我以前遇到过一些问题。但我想是时候学习它了!使用async.map和async.filter可以解决这个问题,谢谢@peterl!我已经看过了承诺以前是,但因为我主要使用nodejs承诺,这让我很困惑,这是一种不同于回调的编程方式。我需要花一些时间来学习它们,因为它们是ECMAScript 6的一部分。对教程或文档有什么建议吗?html5rocks(这是一个非常适合所有html内容的网站)有一篇关于承诺的好文章。它更像是一篇高水平的文章,但它是一个很好的起点: