Создание обещаний по запросам внутри цикла for - PullRequest
0 голосов
/ 10 октября 2018

Я пытаюсь написать код 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, не в состоянии получить концепции обещаний :(.я знаю, где я ошибаюсь и как я могу это исправить.

Объяснение того, что происходит, очень полезно в моих будущих проектах.

Спасибо

Ответы [ 2 ]

0 голосов
/ 10 октября 2018

Когда я запутываюсь, я всегда делаю разлагаю .Соберите кусочки одну за другой и убедитесь, что все работает.Пытаясь понять ваш код, я получаю что-то вроде этого ...

Каждая функция для входа в систему, получения "суммы задач" из БД и получения "счета задач" из БД.(Задача sum / count - это то, что, как я догадался, были до запросов. Переименуйте, как считаете нужным).

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() ...

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;
    });
}
0 голосов
/ 10 октября 2018

Я думаю, что ваша общая структура должна быть примерно такой.Самая большая проблема - не возвращать обещания, когда это необходимо.С «циклом выполнения» обещаний немного сложно зайти, но если вы можете выполнять их параллельно, то проще всего сделать это Promise.all Если вам нужно объединить данные, прежде чем вы сможете выполнить следующий запрос, тогда вам нужносделать несколько Promise.all().then().Причина, по которой вы получаете пустой массив [], заключается в том, что ваш цикл for создает обещания, но не ожидает их завершения.

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));
    });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...