我正在尝试制作一个scraper,但似乎无法按正确的顺序执行代码。我需要在标题和艺术家功能之后执行相册/相册请求功能。我知道node.js对这类事情很奇怪,但我试过把东西到处移动,但仍然没有成功。
这是代码
请原谅混乱和多余的调试代码。
电流输出:
TESTED!!!
req
No error
Pentemple - Pazuzu 2
Now Playing: Pentemple - Pazuzu 2
10
Pentemple
10
Pentemple
1
{ artist: '',
title: '',
album: '',
albumArt: '',
testval: 'TESTED!!!' }
xtest
由于异步请求调用,响应可能不正常,因此为了保持顺序,您需要在上一个请求的回调中进行下一个请求调用。以下是相同的示例-
request(url1, function(err, res, html){
if(!err)
{
// url1 successfully returned , call another dependent url
request(url2, function(err2, res2, html2){
if(!err2)
{
// url2 successfully returned, go on with another request call and so on ...
}
});
}
else
{
// first call failed, return gracefully here --
callback(err); // if you have any
}
})
然而,正如前面的答案所建议的,这是反模式的,会导致混乱和混乱的代码,称为末日金字塔或回调地狱。
我建议使用出色的asyncnpm模块,然后可以将相同的代码写成-
var async = require('async');
async.waterfall([
function(callback) {
request(url1, function(error, res, html){
callback(null, res, html);
});
},
function(res1, html1, callback) {
request(url1, function(error, res, html){
callback(null, res1, html1, res, html);
});
} // ... AND SO ON
], function (err, result) {
// the result contains the response sent by the last request callback
if(!err)
{
// use your data
}
});
JavaScript是异步的。如果请求相互依赖,我建议使用回调,这样当一个请求完成时,它就会调用下一个请求。
在大多数情况下,用Javascript执行请求具有异步性质。这意味着请求不会阻塞整个过程。要在请求完成时执行和操作,需要使用回调。回调是在请求处于完成状态后添加到事件循环队列中的函数。让reqeust一个接一个地运行的最简单方法(但肯定不是最好的方法)是在第一次回调中调用第二个请求,在第三次回调时调用第三个请求,依此类推
request(profileurl, function (error, response, html) {
console.log("req");
if (!error) {
// ...
request(albumurl, function (error, response, html) {
if (!error) {
// ...
request(albumurl, function (error, response, html) {
// ...
});
});
} else {
console.log("ERROR: " + error);
}
});
但这种做法被认为是反模式的,被称为末日金字塔,因为嵌套回调会使代码变得不可读、难以测试和维护。
良好做法被认为是使用承诺。ES2015"开箱即用"。但是如果你使用ES5,你应该为它们使用一些额外的模块,比如:requestpromise或Q.