use*_*355 13 javascript for-loop node.js
我有以下代码:
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);
});
Run Code Online (Sandbox Code Playgroud)
有没有人有关于如何延迟每个循环迭代的建议for loop
?比如说,代码在每次迭代完成后等待10秒.我尝试setTimeout
但没有管理那个工作.
Tro*_*ott 16
您可以按以下间隔设置执行代码的超时时间,如下所示:
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);
}
Run Code Online (Sandbox Code Playgroud)
所以第一个立即运行(间隔*0为0),第二个运行十秒后运行等.
您需要发送i
最终参数,setTimeout()
以便将其值绑定到函数参数.否则,访问数组值的尝试将超出范围,您将获得undefined
.
Rod*_*ros 16
另一种选择是使用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();
});
Run Code Online (Sandbox Code Playgroud)
Luc*_*iva 16
async/await
我是异步库的忠实粉丝,我已经使用了很长时间.但是,现在有了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
}
Run Code Online (Sandbox Code Playgroud)
好多了,不是吗?在我进入的是如何在细节fetchPage()
和fetchUrls()
做工,让我们先回答你的,以获取下一个页面之前如何等问题.睡眠功能非常简单:
async function sleep(millis) {
return new Promise(resolve => setTimeout(resolve, millis));
}
Run Code Online (Sandbox Code Playgroud)
您可以在此处获得有关其工作原理的完整说明.
好的,回到其他功能.该request
库具有可以使用的启用承诺的版本async/await
.我们来看看如何fetchPage()
实施:
async function fetchPage(url) {
return await request({
url: url,
transform: (body) => cheerio.load(body)
});
}
Run Code Online (Sandbox Code Playgroud)
既然request
回来了承诺,我们就可以await
了.我也抓住机会使用了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();
Run Code Online (Sandbox Code Playgroud)
要request
与promises一起使用,请按以下方式安装:
npm install request
npm install request-promise-native
Run Code Online (Sandbox Code Playgroud)
然后require("request-promise-native")
在你的代码中,就像上面的例子一样.
aps*_*ers 10
既然你已经在使用async
,async.wilst
那么就可以很好地替代它for
.
whilst
是一个while
类似异步的函数.每次迭代仅在前一次迭代调用其完成回调之后运行.在这种情况下,我们可以简单地将完成回调的执行推迟10秒setTimeout
.
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
);
Run Code Online (Sandbox Code Playgroud)
小智 6
以下是在 for 循环中提供延迟的示例代码。
const sleep = (milliseconds) => {
const date = Date.now();
let currentDate = null;
do {
currentDate = Date.now();
} while (currentDate - date < milliseconds);
};
for (let index = 0; index < 10; index++) {
console.log(index);
sleep(1000);
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
27429 次 |
最近记录: |