简体   繁体   English

在for循环中解析云代码承诺

[英]Parse Cloud Code Promises in a for loop

As the title states, I'm having trouble with Promises in Parse. 如标题所示,我在解析中遇到了Promises问题。

I'm struggling to firstly understand exactly how Promises themselves work, especially in Parse. 我正在努力首先准确地了解Promises本身的工作方式,尤其是在Parse中。

I have been stuck on this for about three weeks and the closest I've come to a solution is having an empty array returned. 我已经坚持了大约三个星期,而最接近解决方案的是返回一个空数组。

What I'm trying to do is scrape a site and then create objects from the table (this is working) 我正在尝试做的是刮取一个站点,然后从表中创建对象(这是可行的)

Where there trouble comes in, is I am then running a for loop on the results and querying each Dam name to get the resulting objectid from the database. 问题出在哪里,然后我在结果上运行一个for循环,并查询每个Dam名称以从数据库中获取结果objectid。

Here is my code: 这是我的代码:

var c = new Crawler({
    maxConnections: 10,
    // This will be called for each crawled page
    callback: function(err, res, done) {
        if (err) {
            console.log(err);
        } else {
            var $ = res.$;
            // $ is Cheerio by default
            //a lean implementation of core jQuery designed specifically for the server
            console.log($("title").text());
        }
        done();
    }
});

The Function which Creates objects from the Dom and adds them to an array: 从Dom创建对象并将其添加到数组的函数:

function getDamObjects(Dom) {
    var dom = Dom;
    var LevelObjects = [];

    for (i = 1; i < dom.length - 1; i++) {
        var TableRow = dom.eq(i);

        var NameString = TableRow.children().eq(0).text();
        var RiverString = TableRow.children().eq(1).text();
        var FSCString = TableRow.children().eq(4).text();
        var ThisWeekString = TableRow.children().eq(5).text();
        var LastWeekString = TableRow.children().eq(6).text();
        var LastYearString = TableRow.children().eq(7).text();

        NameString = NameString.replace('#', '');
        NameString = NameString.replace('$', '');
        NameString = NameString.replace('&', '');
        NameString = NameString.replace('@', '');

        ThisWeekString = ThisWeekString.replace('#', '');
        ThisWeekString = ThisWeekString.replace('$', '');
        ThisWeekString = ThisWeekString.replace('&', '');
        ThisWeekString = ThisWeekString.replace('@', '');

        LastWeekString = LastWeekString.replace('#', '');
        LastWeekString = LastWeekString.replace('$', '');
        LastWeekString = LastWeekString.replace('&', '');
        LastWeekString = LastWeekString.replace('@', '');

        LastYearString = LastYearString.replace('#', '');
        LastYearString = LastYearString.replace('$', '');
        LastYearString = LastYearString.replace('&', '');
        LastYearString = LastYearString.replace('@', '');

        var level = {};
        /*
        getDamObject(NameString).then(function(DamObject){
        let DamID = DamObject.id;
        */
        level['Dam'] = NameString; //DamID;
        level['ThisWeek'] = ThisWeekString;
        level['LastWeek'] = LastWeekString;
        level['LastYear'] = LastYearString;

        LevelObjects.push(level);
    };
    return LevelObjects;
};

The Get Dam Object Code: 获取大坝目标代码:

function getDamObject(Dam) {
    var promise = new Parse.Promise();

    var query = new Parse.Query("DayZeroDams");
    query.equalTo("Name", Dam);
    query.first().then(function(DamObject) {
        promise.resolve(DamObject);
    }, function(error) {
        promise.reject(error);
    });

    return promise;
}

The Cloud Code Called: 云代码称为:

Parse.Cloud.define('jsdom', function(request, response) {
    c.queue([{
        uri: 'xxxxxx',
        // The global callback won't be called
        callback: function(err, res, done) {
            if (err) {
                response.error(err);
            } else {
                var $ = res.$;
                var ResultsArray = [];
                var dom = res.$('#mainContent_tw').children('tr');
                return Parse.Promise.as().then(function() {
                    var promise = Parse.Promise.as();
                    var LevelObjects = getDamObjects(dom);
                    _.each(LevelObjects, function(DamLevel) {
                        promise = promise.then(function() {
                            var Name = DamLevel["Dam"];
                            var query = new Parse.Query("DayZeroDams");
                            query.equalTo("Name", Name);
                            return query.first().then(function(result) {
                                let damID = result.id;
                                ResultsArray.push(damID);
                                return Parse.Promise.as();
                            }, function(error) {
                                response.error(error);
                            });
                        });
                    });
                    return promise;
                }).then(function() {
                    response.success(ResultsArray);
                }, function(error) {
                    response.error(error);
                });
                //response.success(LevelObjects);
            }
            done();
        }
    }]);
});

Please take note that I am fairly novice when it comes to Javascript, I have only recently started learning it in order to work with my server code. 请注意,关于Javascript,我还是一个新手,我只是最近才开始学习它,以便与服务器代码一起使用。

Convert getDamObjects into an async function and then await the result of each row, pushing it to the array: getDamObjects转换为异步函数,然后await每一行的结果,并将其推送到数组:

function replaceSymbols(input) {
  return input.replace(/[#\$&@]/g, '');
}
async function getDamObjects(Dom) {
  const dom = Dom;
  const levelObjects = [];
  for (let i = 1; i < dom.length - 1; i++) {
    const children = dom.eq(i).children();

    const NameString = replaceSymbols(children.eq(0).text());
    const RiverString = children.eq(1).text();
    const FSCString = children.eq(4).text();
    const ThisWeek = replaceSymbols(children.eq(5).text());
    const LastWeek = replaceSymbols(children.eq(6).text());
    const LastYear = replaceSymbols(children.eq(7).text());

    const Dam = await getDamObject(NameString);
    levelObjects.push({
      Dam,
      ThisWeek,
      LastWeek,
      LastYear,
    });
  }
  return levelObjects;
}

Remember that now that getDamObjects is an async function, it will return a Promise that resolves to the array once iterations are complete. 请记住,既然getDamObjects是一个异步函数,一旦迭代完成,它将返回一个可解析到数组的Promise。 Consume it using await getDamObjects in another async function (or use .then ) 在另一个异步函数中使用await getDamObjects来使用它(或使用.then

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM