Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/36.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 使我的异步代码与setTimeout同步。我需要承诺吗?_Javascript_Node.js_Asynchronous_Request_Promise - Fatal编程技术网

Javascript 使我的异步代码与setTimeout同步。我需要承诺吗?

Javascript 使我的异步代码与setTimeout同步。我需要承诺吗?,javascript,node.js,asynchronous,request,promise,Javascript,Node.js,Asynchronous,Request,Promise,我正在为一个特定的网站构建一个数据刮板。因为我只想每10秒发出一个请求,所以我将其设置为setTimeout循环,该循环将url作为我手动输入的url数组的参数。在回调中,它请求此url并解析响应,将数据推送到一个新的结构化数组中,以便最终将其转换为csv。我将粘贴下面的完整代码以及我的依赖项 问题是,这些请求中大约有五分之一返回为未定义。我认为超时函数会处理这个问题,程序会同步运行。我显然错了。研究这一点,我发现很多人使用承诺依赖来订购异步请求。我的问题是:这有必要吗?或者我可以调整回调/设置

我正在为一个特定的网站构建一个数据刮板。因为我只想每10秒发出一个请求,所以我将其设置为setTimeout循环,该循环将url作为我手动输入的url数组的参数。在回调中,它请求此url并解析响应,将数据推送到一个新的结构化数组中,以便最终将其转换为csv。我将粘贴下面的完整代码以及我的依赖项

问题是,这些请求中大约有五分之一返回为未定义。我认为超时函数会处理这个问题,程序会同步运行。我显然错了。研究这一点,我发现很多人使用承诺依赖来订购异步请求。我的问题是:这有必要吗?或者我可以调整回调/设置超时,使其在不添加其他依赖项的情况下工作

编辑由于不清楚,我在这里复制的正是我希望此应用程序执行的操作: 我希望程序接受一个请求,返回一个json字符串,解析该json字符串中的数据,将该数据添加到数组中,并将该数组导出为csv。我想循环这个功能,这样它就可以对一长串URL执行此操作,但我希望它一次只发出一个请求,并等待迭代到下一个请求,直到从初始响应中收集到所需的数据。我只想每10秒发送一个请求

这是我的密码:

var express = require('express');
var fs = require('fs');
var request = require('request');
var cheerio = require('cheerio');
var app     = express();

var arr = [];

var url = //A bunch of urls that I'm leaving out to conserve space


i = 0;
function timeout() {
    setTimeout(function() {
        request(url[i], function(error, response, html){     
            if(error){
                console.log(error);
            } else {

                var $ = cheerio.load(html);

                var company, industry, size, website, type;

                var inArr = [];
                $('div .image-wrapper img').filter(function(){
                    var data = $(this);
                     company = data.attr('alt');
                     inArr.push("\"" + company + "\"");
               })

                 $('.industry p').filter(function(){
                     var data = $(this);            
                     industry = data.text();  
                     inArr.push("\"" + industry + "\"");
                })

                 $('.company-size p').filter(function(){
                     var data = $(this);                 
                     size = data.text();
                     inArr.push("\"" + size + "\"");
                })

                 $('.website p a').filter(function(){
                     var data = $(this);                 
                     website = data.text();
                     inArr.push("\"" + website + "\"");
                })

                 $('.type p').filter(function(){
                     var data = $(this);                 
                     type = data.text();
                     inArr.push("\"" + type + "\"");
                })


                arr.push(inArr);
                console.log("I just sourced data for " + company);

                if (i === url.length - 1) {
                    clearTimeout(timeout);
                    console.log("All done!")
                    var csvContent;
                    arr.forEach(function(infoArray, index){

                       dataString = infoArray.join(",");
                       csvContent += index < arr.length ? dataString+ "\n" : dataString;

                    });
                    fs.writeFile('output.csv', csvContent, function(err){
                        console.log('File successfully written! - Check your project directory for the output.csv file');
                    });

                } else {
                    i++;
                    timeout();                  
                }
            }

        });
    }, 10000);

};


timeout();
var express=require('express');
var fs=需要('fs');
var请求=要求(“请求”);
var cheerio=需要('cheerio');
var-app=express();
var-arr=[];
var url=//为节省空间而省略的一组url
i=0;
函数超时(){
setTimeout(函数(){
请求(url[i],函数(错误,响应,html){
如果(错误){
console.log(错误);
}否则{
var$=cheerio.load(html);
var公司、行业、规模、网站、类型;
var-inar=[];
$('div.image wrapper img').filter(函数(){
var数据=$(此);
公司=data.attr('alt');
内部推送(“\”+公司+“\”);
})
$('.industry p').filter(函数(){
var数据=$(此);
industry=data.text();
内部推送(“\”+行业+“\”);
})
$('.company size p').filter(函数(){
var数据=$(此);
size=data.text();
一次推送(“\”+大小+“\”);
})
$('.website p a').filter(函数(){
var数据=$(此);
网站=data.text();
推送(“\”+网站+“\”);
})
$('.type p').filter(函数(){
var数据=$(此);
type=data.text();
自动推送(“\”+类型+“\”);
})
arr.push(inArr);
log(“我刚刚为”+公司获取了数据);
if(i==url.length-1){
clearTimeout(超时);
log(“全部完成!”)
var CSV含量;
arr.forEach(函数(infoArray,索引){
dataString=infoArray.join(“,”);
csvContent+=索引
尝试调整
js
以声明引用
setTimeout
的变量。在问题的
js
中,调用
clearTimeout()
时使用
timeout
作为参数,尽管
timeout
是一个函数,而不是对
timeout()
中调用的
setTimeout
的引用。在下面的
js
中,
t
被声明为
timeout
函数外部的变量,设置为
setTimeout
timeout()调用的引用

语法

var timeoutID = window.setTimeout(func, [delay, param1, param2, ...]);
var timeoutID = window.setTimeout(code, [delay]);
var arr=[];
var url=[0,1,2,3,4,5,6,7,8,9];
var i=0;
var t=null;
函数超时(){
t=设置超时(函数(){
(功能(){
var-inar=[];
内推(一)
arr.push(inArr);
log(“我刚刚为“+I,t”获取了数据);
if(i==url.length-1){
清除超时(t);
log(“全部完成!”,i,url.length-1,arr)
}否则{
i++;
超时();
}
}());
},1000);//将stacksnippets的持续时间缩短为“1000”
};

超时()如果这里真正的问题是您希望一个接一个地发送请求,但间隔不超过10秒,那么您可以通过制作一个小包装器函数来完成,该函数告诉您下次调用的时间:

var request = require('request');

function requestNext(url, callback, delay, nextCallback) {
    var start = Date.now();
    request(url, function(error, response, html) {
        callback(error, response, html);
        var elapsed = Date.now() - start;
        var wait = Math.max(delay - elapsed, 0);
        // schedule next call to request()
        setTimeout(nextCallback, wait);
    });
}
然后,只需调用requestNext(),指定延迟时间和第二个回调,该回调将告诉您何时进行下一次调用

然后,在您的特殊情况下,您可以将其与如下重复函数一起使用:

function getURLs(urls, delay, processCallback, doneCallback) {
    var index = 0;
    var data = [];

    function next() {
        if (index < urls.length) {
            requestNext(urls[index++], function(err, response, html) {
                // need to decide what you want do for error handling here
                // continue? stop further processing?
                data.push(processCallback(err, response, html));
            }, delay, next);
        } else {
            doneCallback(null, data);
        }
    }
    next();
}

getURLs(urlArray, 10000, processResult, function(err, dataArray) {
   if (!err) {
       // results are in dataArray
   }
});
function processResult(err, response, html) {
    // your code to process a page here
    // return the final result as a return value and it will be collected for you
}
“问题是大约五分之一的请求返回为未定义的。”
clearTimeout(timeout)的预期结果是什么
setTimeout
timeout
内未声明初始或以后设置的函数