Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/423.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.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 Array.forEach中的Node.Js异步请求在编写json文件之前未完成_Javascript_Json_Node.js_Request_Cheerio - Fatal编程技术网

Javascript Array.forEach中的Node.Js异步请求在编写json文件之前未完成

Javascript Array.forEach中的Node.Js异步请求在编写json文件之前未完成,javascript,json,node.js,request,cheerio,Javascript,Json,Node.js,Request,Cheerio,我正在制作一个web scraper Node.js应用程序,它可以从各种URL获取工作描述文本。。我目前有一个名为jobObj的作业对象数组,代码在每个url中循环,对html发出请求,使用cheerio模块加载然后最终使用jobName和jobDesc键创建一个新对象,并将其推送到一个新的对象数组中,然后将其写入json文件 所有这些目前都有效,但是编写的json文件的完整性是非常随机的,通常只包含一个完整的作业帐户。我认为这可能是因为forEach循环完成得比异步请求函数快得多,从而导致在

我正在制作一个web scraper Node.js应用程序,它可以从各种URL获取工作描述文本。。我目前有一个名为jobObj的作业对象数组代码在每个url中循环,对html发出请求,使用cheerio模块加载然后最终使用jobName和jobDesc键创建一个新对象,并将其推送到一个新的对象数组中,然后将其写入json文件

所有这些目前都有效,但是编写的json文件的完整性是非常随机的,通常只包含一个完整的作业帐户。我认为这可能是因为forEach循环完成得比异步请求函数快得多,从而导致在请求回调完成之前执行fs.writefile。我添加了一个计数器来监视请求处于哪个阶段,并且只在counter==jobObj.length写入json文件一次,但json文件仍然没有完全完成

我是node.js新手,如果有人能指出我的错误,我将不胜感激

var jobObj = [
{
id:1, 
url:"https://www.indeed.co.uk/cmp/Daffodil-IT/jobs/Lead-Junior-Website-Developer-59ea7d446bdf1253?q=Junior+Web+Developer&vjs=3",
}, 
{
id:2, 
url:"https://www.indeed.co.uk/cmp/Crush-Design/jobs/Middleweight-Web-Developer-541331b7885c03cf?q=Web+Developer&vjs=3",
},
{
id:3,
url:"https://www.indeed.co.uk/cmp/Monigold-Solutions/jobs/Graduate-Web-Software-Engineer-a5787dc322c0ca36?q=Web+Developer&vjs=3",
},
{
id:4,
url:"https://www.indeed.co.uk/cmp/ZOO-DIGITAL-GROUP-PLC/jobs/Web-Developer-5cdde1c3b0b7b8d0?q=Web+Developer&vjs=3",
},
{
id:5,
url:"https://www.indeed.co.uk/viewjob?jk=9cc3d8c637c41067&q=Web+Developer&l=Sheffield&tk=1cf5di52e9u0ocam&from=web&vjs=3",
}
];


app.get('/myform', function(req, res){

res.send("<h1>" + `scanning ${jobObj.length} urls for job description text` + "</h1>");
//make assign input form data to node "url" variable

//Compnonents for a request counter
var jobs = new Array;
function scrapeFinished(){console.log("all websites scraped!");};
var itemsProcessed = 0;   

jobObj.forEach(function(item){

    request(item.url, function(err, res, html){

        if(!err){

            var $ = cheerio.load(html);
            var newJob = new Object;
            $('#job_summary').each(function(){
                var data = $(this);
                var textout = data.text();
                newJob.jobDesc = textout;    
            });

            $('.jobtitle').each(function(){
                var data = $(this);
                var jobtitle = data.text();
                newJob.jobName = jobtitle;
            });

            jobs.push(newJob);
            itemsProcessed++;
            console.log(item.url + " scraped");  

            if(itemsProcessed === jobObj.length){
            scrapeFinished();

            fs.writeFile('output.json', JSON.stringify(jobs, null, "\t"), function(err){ 
            if(!err){console.log("output.json file written")}
            })
            }
        }      
    })           
})


})
forEach以同步方式运行,因此无论需要多少时间来废弃网页,它都不会为下一个数组项运行。这里可能会出现问题的是,您的代码可能会在销毁网页之前在数组中推送一个对象。这就是为什么会得到一个空对象。您要做的是在程序访问完URL后推送对象。 做这样的事

 jobObj.forEach(function (item) {

    var newJob = new Object;
    request(item.url, function (err, res, html) {
        // Scrap URL and save values in newJob 
    });
            jobs.push(newJob);
});

如果代码在完成请求之前仍推空对象,则考虑使用模块。 移动push()没有解决问题,但确实导致总共有3个工作帐户完成!当前pb!将有一个与异步模块,干杯!虽然异步请求会在等待回调时跳到push()函数吗?不会。我不这么认为。将push()移到请求之外后,新的输出是什么?

 jobObj.forEach(function (item) {

    var newJob = new Object;
    request(item.url, function (err, res, html) {
        // Scrap URL and save values in newJob 
    });
            jobs.push(newJob);
});