Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/411.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 延迟节点js中的每个循环迭代,异步_Javascript_Node.js_For Loop - Fatal编程技术网

Javascript 延迟节点js中的每个循环迭代,异步

Javascript 延迟节点js中的每个循环迭代,异步,javascript,node.js,for-loop,Javascript,Node.js,For Loop,我的代码如下: var request = require('request'); var cheerio = require ("cheerio"); var async= require("async"); var MyLink="www.mylink.com"; async.series([ function(callback){ request(Mylink, function (error, response, body) {

我的代码如下:

var request = require('request');
var cheerio = require ("cheerio");
var async= require("async");

var MyLink="www.mylink.com";

    async.series([

        function(callback){
            request(Mylink, function (error, response, body) {
                if (error) return callback(error); 
                var $ = cheerio.load(body);
                //Some calculations where I get NewUrl variable...
                TheUrl=NewUrl;
                callback();
            });
        },
        function(callback){
            for (var i = 0; i <=TheUrl.length-1; i++) {
                var url = 'www.myurl.com='+TheUrl[i];
                request(url, function(error, resp, body) { 
                    if (error) return callback(error); 
                    var $ = cheerio.load(body);
                    //Some calculations again...
                    callback();
                });
            };
        }
      ], function(error){
        if (error) return next(error);
    });
var request=require('request');
var cheerio=要求(“cheerio”);
var async=require(“异步”);
var MyLink=“www.MyLink.com”;
异步系列([
函数(回调){
请求(Mylink、函数(错误、响应、正文){
if(error)返回回调(error);
var$=总负荷(车身);
//我得到NewUrl变量的一些计算。。。
TheUrl=NewUrl;
回调();
});
},
函数(回调){

对于(var i=0;i,您可以按如下所示的递增间隔设置代码执行超时:

var interval = 10 * 1000; // 10 seconds;

for (var i = 0; i <=TheUrl.length-1; i++) {
    setTimeout( function (i) {
        var url = 'www.myurl.com='+TheUrl[i];
        request(url, function(error, resp, body) { 
            if (error) return callback(error); 
            var $ = cheerio.load(body);
            //Some calculations again...
            callback();
        });
    }, interval * i, i);
}
npm install request
npm install request-promise-native
var interval=10*1000;//10秒;

对于(var i=0;i,因为您已经在使用
async
async.wilst
可以很好地替代
for

while
是一个类似于
while
的异步函数。每次迭代仅在上一次迭代调用其完成回调后运行。在这种情况下,我们可以使用
setTimeout
将完成回调的执行延迟10秒

var i = 0;
async.whilst(
    // test to perform next iteration
    function() { return i <= TheUrl.length-1; },

    // iterated function
    // call `innerCallback` when the iteration is done
    function(innerCallback) {
        var url = 'www.myurl.com='+TheUrl[i];
        request(url, function(error, resp, body) { 
            if (error) return innerCallback(error); 
            var $ = cheerio.load(body);
            //Some calculations again...

            // wait 10 secs to run the next iteration
            setTimeout(function() { i++; innerCallback(); }, 10000);
        });
    },

    // when all iterations are done, call `callback`
    callback
);
var i=0;
异步的(
//测试以执行下一次迭代

function(){return i另一种选择是使用
async.eachSeries
。例如:

async.eachSeries(TheUrl, function (eachUrl, done) {
    setTimeout(function () {
        var url = 'www.myurl.com='+eachUrl;
        request(url, function(error, resp, body) { 
            if (error) return callback(error); 
            var $ = cheerio.load(body);
            //Some calculations again...
            done();
        });
    }, 10000);
}, function (err) {
    if (!err) callback();
});
使用
async/await
我非常喜欢异步库,我已经使用了很长时间。但是,现在有了。您的代码变得更容易阅读。例如,这将是您的主要功能:

const urls = await fetchUrls(INITIAL_URL);

for (const url of urls) {
    await sleep(10000);
    const $ = await fetchPage(url);
    // do stuff with cheerio-processed page
}
更好,不是吗?在我详细介绍
fetchPage()
fetchurl()
如何工作之前,让我们先回答一下您关于如何等待才能获取下一页的问题。sleep函数非常简单:

async function sleep(millis) {
    return new Promise(resolve => setTimeout(resolve, millis));
}
你可以在我的另一个答案中得到它是如何工作的完整解释

好的,回到其他函数。
请求
库有一个启用承诺的版本,可以与
async/await
一起使用。让我们看看
fetchPage()
是如何实现的:

async function fetchPage(url) {
    return await request({
        url: url,
        transform: (body) => cheerio.load(body)
    });
}
由于
request
正在返回一个承诺,我们可以
等待它。我还借此机会使用
transform
属性,它允许我们在解析承诺之前转换响应体。我正在通过Cheerio传递它,就像您在代码中所做的那样

最后,
fetchUrls()
只需调用
fetchPage()
并对其进行处理以获取URL数组,然后再解析其承诺。以下是完整代码:

const
    request = require("request-promise-native"),
    cheerio = require("cheerio");

const
    INITIAL_URL = "http://your-initial-url.com";

/**
 * Asynchronously fetches the page referred to by `url`.
 *
 * @param {String} url - the URL of the page to be fetched
 * @return {Promise} promise to a cheerio-processed page
 */
async function fetchPage(url) {
    return await request({
        url: url,
        transform: (body) => cheerio.load(body)
    });
}

/**
 * Your initial fetch which will bring the list of URLs your looking for.
 *
 * @param {String} initialUrl - the initial URL
 * @return {Promise<string[]>} an array of URL strings
 */
async function fetchUrls(initialUrl) {
    const $ = await fetchPage(initialUrl);
    // process $ here and get urls
    return ["http://foo.com", "http://bar.com"];
}

/**
 * Clever way to do asynchronous sleep. 
 * Check this: https://stackoverflow.com/a/46720712/778272
 *
 * @param {Number} millis - how long to sleep in milliseconds
 * @return {Promise<void>}
 */
async function sleep(millis) {
    return new Promise(resolve => setTimeout(resolve, millis));
}

async function run() {
    const urls = await fetchUrls(INITIAL_URL);
    for (const url of urls) {
        await sleep(10000);
        const $ = await fetchPage(url);
        // do stuff with cheerio-processed page
    }
}

run();

然后在你的代码中加入
require(“request promise native”)
,就像上面的例子一样。

为什么我不能把最后一行从
},interval*I,I);
改成
},interval*1,I);
I改成1
?如果我想要一个恒定的interval,那么代码就不能工作。
setTimeout()
立即返回。它不会坐在那里等待超时,然后再将控制权返回到
for
循环。因此,如果使用
interval*1
(与
interval
相同),那么您将在未来十秒钟内一次性运行所有操作(或多或少——它们将相隔几毫秒,但仅此而已)。但如果使用
interval*i
,则第一次“立即”通过,“未来十秒”循环第二次“未来二十秒”第三次,等等。好的,尝试了
interval*1
,但没有结果…但我理解你的意思!Thansk。请注意,setTimeout有一个最大值,如果它达到2147483647,它将中断。是否可以在特定时间设置延迟?例如,每30分钟一次?