在for循环内的查询上创建承诺

时间:2018-10-10 14:26:31

标签: node.js promise

我正在尝试编写执行以下操作的Node.js代码。

  1. 连接到Salesforce实例。
  2. 获取过去7天的内容,并进行遍历。
  3. 在其中运行2个查询,并将结果推入数组。
  4. 在另一个函数中显示该值。

这是我的JS代码。

var jsforce = require("jsforce");
var moment = require('moment');

function connectToEP() {
    var main_Obj = {};
    var response_Obj = {};
    var pastSevenDaysArray = [];
    var conn = new jsforce.Connection();
    var beforeSevenDays = moment().subtract(7, 'days').format('YYYY-MM-DD');
    var today = moment().startOf('day');
    var i = 0;


    conn.login("myUid", "myPwd").then(() => {
        console.log("Connected To Dashboard");
        for (var m = moment(beforeSevenDays); m.diff(today, 'days') <= 0; m.add(1, 'days')) {
            conn.query("SELECT SUM(Total_ETA_of_all_tasks__c), SUM(Total_ETA__C) from Daily_Update__c where DAY_ONLY(createddate)= " + m.format('YYYY-MM-DD')).then(() => {
                console.log("B1");
                var z = response_Obj.aggrRes;
                response_Obj.aggrRes = res;
                pastSevenDaysArray.push({ z: res });
                console.log("B1 Exit");

            }).then(() => {
                conn.query("SELECT count(Id), Task_Type__c FROM Daily_Task__c where DAY_ONLY(createddate) = " + m.format('YYYY-MM-DD') + " group by Task_Type__c").then(() => {
                    console.log("B2");

                    var z = response_Obj.aggrRes;
                    response_Obj.aggrRes = res;
                    pastSevenDaysArray.push({ z: res });
                    console.log("B2 Exit");

                })
            })
        }
        return Promise.resolve(pastSevenDaysArray);
    }).then((data) => {
        console.log(typeof data);
        updateMessage(JSON.stringify(data));
        console.log(typeof data);
    });

}
function updateMessage(message) {
    console.log("XXXXXXXXXXXX");
    console.log(message);
    console.log("XXXXXXXXXXXX");
}
function socketNotificationReceived() {
    console.log("socket salesforce rec");
    connectToEP();
}

socketNotificationReceived();

当我运行这段代码时,我得到的输出是

socket salesforce rec
Connected To Dashboard
object
XXXXXXXXXXXX
[]
XXXXXXXXXXXX
object
B1
B1
B1
B1
B1
B1
B1
B1

我是这个js平台的新手,无法获得Promise概念:(。请让我知道我出了错以及如何解决它。

解释发生的事情对我将来的项目很有帮助。

谢谢

2 个答案:

答案 0 :(得分:1)

当我感到困惑时,我总是做的事情是分解。一件一件地建造,并确保每件作品都能正常工作。试图理解您的代码,我得到了类似的东西...

每个函数都用于登录,从db获取“任务总数”和从db获取“任务计数”。 (任务的总和/计数是我猜到的查询所要达到的值。您认为合适的话可以重命名)。

var jsforce = require("jsforce");
var moment = require('moment');

function login(conn) {
    return conn.login("myUid", "myPwd");
}

function queryTaskSumForDay(conn, m) {
    return conn.query("SELECT SUM(Total_ETA_of_all_tasks__c), SUM(Total_ETA__C) from Daily_Update__c where DAY_ONLY(createddate)= " + m.format('YYYY-MM-DD'));
}

function queryTaskCountForDay(conn, m) {
    return conn.query("SELECT count(Id), Task_Type__c FROM Daily_Task__c where DAY_ONLY(createddate) = " + m.format('YYYY-MM-DD') + " group by Task_Type__c");
}

有了这些工作,就可以很容易地得出给定日期的总数和计数。而不是将它们返回到数组中(包含两个对象,每个对象都像您的代码一样具有“ z”属性),我选择了具有sum和count属性的更简单的单个对象。您可能需要更改此设置以适合您的设计。请注意,使用Promise.all()一起解决了两个诺言...

function sumAndCountForDay(conn, m) {
    let sum = queryTaskSumForDay(conn, m);
    let count = queryTaskCountForDay(conn, m);
    return Promise.all([sum, count]).then(results => {
        return { sum: results[0], count: results[1] };
    });
}

通过这项工作,使用您的矩逻辑和Promise.all()的想法,很容易在7天内获得一个总计数对象数组。

function sumAndCountForPriorWeek(conn) {
    let promises = [];
    let beforeSevenDays = moment().subtract(7, 'days').format('YYYY-MM-DD');
    let today = moment().startOf('day');
    for (let m = moment(beforeSevenDays); m.diff(today, 'days') <= 0; m.add(1, 'days')) {
        promises.push(sumAndCountForDay(conn, m));
    }
    return Promise.all(promises);
}

工作正常(注意这里的模式吗?),您的OP功能很小,几乎已经过全面测试,因为我们已经测试了所有部分...

function connectToEP() {
    let conn = new jsforce.Connection();
    return login(conn).then(() => {
        return sumAndCountForPriorWeek(conn)
    }).then(result => {
        console.log(JSON.stringify(result));
        return result;
    }).catch(error => {
        console.log('error: ' + JSON.stringify(error));
        return error;
    });
}

答案 1 :(得分:0)

我认为您的总体结构应该是这样的。最大的问题是在需要时不兑现承诺。 Promise的“ for循环”有点困难,但是如果可以并行执行它们,那么最简单的方法是Promise.all如果需要在执行下一个查询之前汇总数据,则您需要执行多个Promise.all().then()。您获得空数组[]的原因是因为您的for循环创建了promise,但不等到它们完成。

var jsforce = require("jsforce");
var moment = require('moment');

function connectToEP() {
  // connectToEP now returns a promise  
  return conn.login("myUid", "myPwd").then(() => {
        console.log("Connected To Dashboard");
        let myQueries = [];
        for (start ; condition ; incrementer) {
            myQueries.push( // Add all these query promises to the parallel queue
                conn.query(someQuery)
                    .then((res) => {
                        return res;
                    })
                    .then((res) => {
                        return conn.query(someQuery).then((res) => {
                            return someData;
                        })
                    })
            )
        }
        return Promise.all(myQueries); // Waits for all queries to finish...
    }).then((allData) => { // allData is an array of all the promise results
        return updateMessage(JSON.stringify(allData));
    });
}