Nodejs中关于async的使用求解
Nodejs中关于async的使用求解
//二.采集目标内容的地址
$.each(one_url,function(i,v){
var temp = v.split(’-’)
temp[1] = 2
console.log(‘a’)
async.series([
function(){
n.get(temp.join(’-’),{decode_response:false,encoding:‘binary’,follow:1},list_url)
}
])
console.log(‘ccccc’)
})
//二。采集分类列表的链接地址
var list_url = function(error,response,body){
var content = new iconv(‘gbk’,‘UTF-8//TRANSLIT//IGNORE’).convert(new Buffer(body,‘binary’)).toString()
console.log($(content).find(’.last’).attr(‘href’))
}
日志中输出
C:\nodejs\node.exe cj39.js
a
ccccc
a
ccccc
a
ccccc
a
ccccc
a
ccccc
a
ccccc
a
ccccc
a
ccccc
a
ccccc
a
ccccc
a
ccccc
a
ccccc
a
ccccc
a
ccccc
a
ccccc
a
ccccc
a
ccccc
undefined
/browse/313-2-2188.html
/browse/23-2-893.html
/browse/14440-2-2188.html
/browse/320-2-2188.html
/browse/322-2-2188.html
undefined
/browse/19018333-2-2188.html
/browse/3157-2-2188.html
/browse/3162-2-2188.html
/browse/323-2-2188.html
/browse/309-2-2188.html
/browse/3166-2-2188.html
/browse/311-2-2188.html
/browse/3163-2-2188.html
/browse/27-2-2188.html
/browse/271-2-2188.html
可以看到async里面没有等待函数执行完成就执行了日志console.log(‘ccc’)的输出。求怎么按顺序执行?
在Node.js中使用async
库来管理异步操作是一个常见的需求,特别是当你需要确保一系列异步任务按顺序执行时。你遇到的问题是因为async.series
中的函数是立即执行的,而你希望它们按照序列的方式执行。
解决方案
为了确保异步操作按顺序执行,你可以使用async.series
的正确方式。此外,你需要确保在所有异步操作完成后才执行后续的日志输出。
示例代码
const async = require('async');
const axios = require('axios');
const iconv = require('iconv-lite');
// 模拟n.get方法
const n = {
get: (url, options, callback) => {
axios.get(url, { responseType: 'arraybuffer' })
.then(response => {
const body = iconv.decode(Buffer.from(response.data), 'gbk');
callback(null, body);
})
.catch(error => {
callback(error);
});
}
};
// 分类列表链接地址处理函数
const list_url = (error, response, body) => {
if (error) {
console.error("Error:", error);
return;
}
const content = iconv.decode(Buffer.from(body), 'gbk');
const href = $(content).find('.last').attr('href');
if (href) {
console.log(href);
} else {
console.log('undefined');
}
};
// 主逻辑
const one_url = [
"browse/313-1-2188.html",
"browse/23-1-893.html",
"browse/14440-1-2188.html",
// 更多URL...
];
async.series(
one_url.map(url => {
return (callback) => {
let temp = url.split('-');
temp[1] = 2;
const modifiedUrl = temp.join('-');
n.get(modifiedUrl, { decode_response: false, encoding: 'binary', follow: 1 }, list_url);
callback(); // 确保回调被调用
};
}),
(err) => {
if (err) {
console.error("Async series error:", err);
return;
}
console.log('All tasks completed.');
}
);
解释
- 模拟
n.get
方法:这里我们使用axios
来模拟n.get
方法,它会发送HTTP请求并返回响应体。 list_url
函数:处理HTTP响应,并提取所需的链接。async.series
:使用async.series
来确保每个URL对应的异步任务按顺序执行。每个任务都包含一个回调函数,该函数在任务完成后调用,以确保async.series
可以继续执行下一个任务。callback()
:在每个任务的最后调用callback()
来通知async.series
当前任务已完成。
通过这种方式,你可以确保所有异步任务按顺序执行,并且在所有任务完成后打印“All tasks completed.”。
async根本就不是这么用的吧,那个地方用series有什么意义。。
这个each怎么使用?第2个参数我不太理解。。可否给个例子说明?
这是 async.map
的正确用法:
var array = [0, 1, 2, 3];
async.map(array, function (item, callback) {
console.log("Transforming item: " + item);
var transformed = item + 1;
callback(null, transformed);
}, function (error, results) {
console.log(results); // => [1, 2, 3, 4]
});
楼主可能对非阻塞模型和 callback
的语法地位都不理解,建议先学点入门的东西再写代码……
你遇到的问题是因为 async.series
中的任务需要一个回调函数来通知它任务已经完成。你当前的代码中没有提供这个回调函数,因此 async.series
认为任务已经立即完成,所以导致后续的 console.log('ccccc')
会立即执行。
为了确保任务按顺序执行,你需要在任务函数中调用传入的回调函数来表示任务已完成。以下是修改后的代码示例:
const async = require('async');
$.each(one_url, function(i, v) {
var temp = v.split('-');
temp[1] = 2;
console.log('a');
async.series([
function(callback) {
n.get(temp.join('-'), { decode_response: false, encoding: 'binary', follow: 1 }, function(error, response, body) {
list_url(error, response, body);
callback(); // 调用回调函数表示任务完成
});
}
]);
console.log('ccccc');
});
// 分类列表链接地址采集
var list_url = function(error, response, body) {
if (error) {
console.error("Error:", error);
return;
}
var content = new iconv('gbk', 'UTF-8//TRANSLIT//IGNORE').convert(new Buffer(body, 'binary')).toString();
console.log($(content).find('.last').attr('href'));
};
在这个修改后的版本中,我添加了一个回调函数 callback
来通知 async.series
任务已经完成。这样可以确保在所有任务完成后才会继续执行后续的代码。