【问题标题】:Parse Cloud Code Promises in a for loop在 for 循环中解析云代码承诺
【发布时间】:2018-04-14 01:16:03
【问题描述】:

正如标题所述,我在 Parse 中遇到了 Promise 问题。

我正在努力首先了解 Promises 本身是如何工作的,尤其是在 Parse 中。

我已经坚持了大约三周,我最接近解决方案的是返回一个空数组。

我正在尝试做的是抓取一个站点,然后从表中创建对象(这是有效的)

问题出在哪里,是我在结果上运行一个 for 循环并查询每个 Dam 名称以从数据库中获取结果 objectid。

这是我的代码:

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();
    }
});

从 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;
};

获取大坝对象代码:

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;
}

调用的云代码:

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();
        }
    }]);
});

请注意,我在 Javascript 方面相当新手,我最近才开始学习它,以便使用我的服务器代码。

【问题讨论】:

  • 在输入代码时考虑使用缩进,它会让你和其他需要阅读它的人更轻松。
  • @CertainPerformance 对此感到抱歉 ^^ 我是新来的,我不确定如何正确格式化我的代码,因为当我将其粘贴到此处时所有缩进都发生了变化,所以我只是遵循四个空格规则.
  • 简而言之,将getDamObjects 设为async 函数,将每个异步调用变成一个promise,并将它们中的每一个都设为await。或者,如果您不希望串行等待,请改用await Promise.all
  • @CertainPerformance 我希望它是连续的(我想我至少会这样做)。您能否发布一个解决方案或至少一个可以为我指明正确方向的示例:)
  • @CertainPerformance PS你有什么理由注释掉云代码功能吗?如果写得不好,对不起

标签: javascript parse-platform promise parse-server parse-cloud-code


【解决方案1】:

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;
}

请记住,现在 getDamObjects 是一个异步函数,一旦迭代完成,它将返回一个解析为数组的 Promise。在另一个异步函数中使用await getDamObjects 使用它(或使用.then

【讨论】:

  • 所以如果我用上面的代码替换我的 getDamObjects,我应该像以前一样引用它吗?如果我将其余部分保持原样,我的代码会等待 levelObjects 吗?
  • 谢谢您的回答
  • @BLE 不,就像我说的,你需要使用await getDamObjects.then 来使用它,因为它返回一个promise。
  • 抱歉这么菜鸟,我不是很懂await函数,是不是我在云代码中引用的时候直接放在getDamObjects前面?
  • 在替换符号函数中,符号参数中必须有'g'吗?
猜你喜欢
  • 2015-05-05
  • 1970-01-01
  • 2017-11-19
  • 2023-03-17
  • 2020-05-14
  • 2015-12-18
  • 1970-01-01
  • 1970-01-01
  • 2016-10-11
相关资源
最近更新 更多