我正在使用node使用cheerio从URL抓取一些数据。
const request=require('request');
const cheerio=require('cheerio');
const Promise = require('promise');
函数getDataParms(parm1, parm2)
返回一个Promise对象。
retrieveAllData(parm1, limit)
为一组更改的参数调用getDataParms
最终输出来自
var test2 = retrieveAllData('foo','2015');
console.log(test2);
节点script.js的输出
// [ Promise { _75: 0, _83: 0, _18: null, _38: null } ]
在某个地方,我没有正确使用Promise方法,也无法知道在哪里。我需要一些经验丰富的眼睛来帮助我弄清楚自己在做错什么。
代码:
const request=require('request');
const cheerio=require('cheerio');
const Promise = require('promise');
var dateVal = new Date();
var test2 = [];
function retrieveAllData(parm1, limit){
var output = [];
var intermediate;
for (var j=1; j <= limit; j++){
var objKey = parm1 + "_data";
var results = {
"data1": null,
[objKey]: null
};
results.data1 = j;
objKey = objKey + "_" + j;
results[objKey] = getDataParms(parm1, j).then(function(value){
//console.log(value);
return value;
});
//console.log(results[objKey]);
output.push(results[objKey]);
}
return output;
}
// Returns a Promise array
function getDataParms(parm1, parm2){
var sourceURL = "http://website/source=" + material + "&parm1=" + parm1 + "&parm2=parm2";
var parsedResults = [];
var metadata = {
record_parm2: time_period,
record_no: null,
record_date: null,
col1: null,
col2: null,
col3: null
};
return new Promise(function(fulfill, reject){
request(sourceURL, function(error,response,html){
if (error){
reject(error);
} else if (!error && response.statusCode == 200){
var $ = cheerio.load(html);
$(".data tr").each(function(i, element){
metadata.record_no = i;
$(this).find("td").each(function(cellindex){
switch(cellindex){
case 0:
metadata.record_date = $(this).text();
break;
case 1:
metadata.col1 = parseFloat($(this).text());
break;
case 2:
metadata.col2 = parseFloat($(this).text());
break;
case 3:
metadata.col3 = parseFloat($(this).text());
break;
}
});
parsedResults.push(metadata);
});
fulfill(parsedResults);
}
});
});
}
var test2 = retrieveAllData('foo','2015');
console.log(test2);
答案 0 :(得分:2)
由于每个getDataParms
调用都返回一个Promise
,因此您应该等待所有此类Promises首先使用Promise.all
解决。另外,由于getDataParms
返回了Promise
,因此消耗retrieveAllData
的{{1}}也应该返回getDataParams
以便最终的Promise
以后可以使用。您应该在results
调用中呼叫var test2 = retrieveAllData(...
,而不是.then
。
retrieveAllData
并使用function retrieveAllData(parm1, limit){
// Create an array of Promises, with `j`'s values being 0 to `limit - 1`:
const allPromises = Array.from(
{ length: limit },
(_, j) => {
// Make j start at 1 rather than 0:
j++;
const objKey = parm1 + "_data_" + j;
// After getDataParms resolves, return an object with keys `data1` and `[objKey]`:
return getDataParms(parm1, j)
.then((parms) => ({
data1: j,
[objKey]: parms
}));
}
);
return Promise.all(allPromises);
}
消费它:
.then
使用retrieveAllData('foo','2015')
.then(test2 => {
console.log(test2);
});
循环而不是起作用看起来像这样:
for
答案 1 :(得分:0)
您需要使用Promise.all
,以下示例可能会对您有所帮助
function retrieveAllData(parm1, limit) {
var output = [];
for (var j = 1; j <= limit; j++) {
output.push(getDataParms(parm1, j));
}
return Promise.all(output);
}
var test2 = retrieveAllData('foo', '2015'); // this will return a promise
test2.then(function (result) {
console.log(result);
})