我是否正确使用此Promise功能

时间:2018-07-12 08:24:25

标签: javascript node.js promise es6-promise

我正在使用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);

2 个答案:

答案 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);
})