Оператор возврата javascript, возвращающий значение undefined

Я тестирую приложение angular js salesforce с помощью транспортира. Мне нужно запросить идентификаторы с помощью SOQL и jsforce, однако, когда я вызываю метод запроса из другого класса, результат возврата не определен. Когда я распечатываю журнал в методе, он показывает, что идентификатор, который я ищу, кажется, теряется в операторе возврата.

var jsforce = require('jsforce');

function querySF() {
  var conn = new jsforce.Connection({
    // you can change loginUrl to connect to sandbox or prerelease env.
    loginUrl: 'https://www.salesforce.com'
  });
  conn.login('some username', 'some password', function(err, userInfo) {
    if (err) {
      return console.error(err);
    }
    // Now you can get the access token and instance URL information.
    // Save them to establish connection next time.
    console.log(conn.accessToken);
    console.log(conn.instanceUrl);
    // logged in user property
    console.log("User ID: " + userInfo.id);
    console.log("Org ID: " + userInfo.organizationId);
    // ...
  }).then(function() {
    conn.query("SELECT Id FROM anObject__c Where name = 'the name'", function(err, result) {
      if (err) {
        return console.error(err);
      }
      var records = [];
      console.log("total : " + result.totalSize);
      console.log("fetched : " + result.records.length);
      // is returning the id
      console.log(result.records[0].Id);
      // the class that calls the methods saves it to a variable, the variable is undefined
      return result.records[0].Id;
    });
  });


}
After updating my code to match Thomas' answer the below is the error I am receiving

Ошибка: Helper.querySF не является функцией TypeError: Helper.querySF не является функцией в Object.it (C: \ LimService \ LSApp \ tests \ specs \ bookingEvents \ EditBookingEventTest.js: 23: 12) в C: \ Users \ nphillips \ AppData \ Roaming \ npm \ node_modules \ protractor \ node_modules \ jasminewd2 \ index.js: 112: 25 в новом ManagedPromise (C: \ Users \ nphillips \ AppData \ Roaming \ npm \ node_modules \ protractor \ node_modules \ selenium-webdriver \ lib \ обещание.js: 1067: 7) в ControlFlow.promise (C: \ Users \ nphillips \ AppData \ Roaming \ npm \ node_modules \ protractor \ node_modules \ selenium-webdriver \ lib \ обещание.js: 2396: 12) в schedulerExecute (C: \ Users \ nphillips \ AppData \ Roaming \ npm \ node_modules \ protractor \ node_modules \ jasminewd2 \ index.js: 95: 18) в TaskQueue.execute_ (C: \ Users \ nphillips \ AppData \ Roaming \ npm \ node_modules \ protractor \ node_modules \ selenium-webdriver \ lib \ prom.js: 2970: 14) в TaskQueue.executeNext_ (C: \ Users \ nphillips \ AppData \ Roaming \ npm \ node_modules \ protractor \ node_modules \ selenium-webdriver \ li b \ обещание.js: 2953: 27) в asyncRun (C: \ Users \ nphillips \ AppData \ Roaming \ npm \ node_modules \ protractor \ node_modules \ selenium-webdriver \ lib \ обещание.js: 2860: 25) в C: \ Пользователи \ nphillips \ AppData \ Roaming \ npm \ node_modules \ protractor \ node_modules \ selenium-webdriver \ lib \ обещание.js: 676: 7


person Nicole Phillips    schedule 23.05.2017    source источник
comment
Не могли бы вы рассказать, как вы используете этот фрагмент кода в другом классе?   -  person maazadeeb    schedule 23.05.2017
comment
return conn.login(...).then(...) и return conn.query(...)   -  person Thomas    schedule 23.05.2017
comment
@Maazsyedadeeb var theId = Helper.querySF;   -  person Nicole Phillips    schedule 23.05.2017
comment
@NicolePhillips Ошибка говорит, что Helper.querySF не является функцией. Что означает Helper в EditBookingEventTest.js строке 23?   -  person Thomas    schedule 24.05.2017
comment
@Thomas - это имя класса, в котором расположен метод.   -  person Nicole Phillips    schedule 24.05.2017
comment
Вы так думаете, но проверяли ли вы это? И вы уверены, что класс предоставляет метод querySF? Вот что имел в виду последний вопрос. Вы проверили, что именно упоминается под именем Helper в этом файле, в этой строке?   -  person Thomas    schedule 24.05.2017
comment
Мы получаем доступ примерно к 30 различным методам в классе одинаково. Внизу вспомогательного класса мы экспортируем метод следующим образом: exports.querySF = querySF ();   -  person Nicole Phillips    schedule 24.05.2017
comment
exports.querySF = querySF; не результат вызванной функции.   -  person Thomas    schedule 24.05.2017
comment
@Thomas Вы должны меня простить, так как я ухожу от автоматизации C # с помощью Selenium и только начинаю с angular js, и у меня нет особых знаний по этому поводу. Возможно, вам придется заключить со мной грубые непрофессиональные условия, чтобы понять, о чем вы спрашиваете.   -  person Nicole Phillips    schedule 25.05.2017


Ответы (1)


Как упоминалось в комментарии, вы забыли несколько return утверждений.

Кроме того, не смешивайте обещания и обратные вызовы. Особенно не используйте оба для обработки одного и того же результата.

var jsforce = require('jsforce');

function querySF() {
    var conn = new jsforce.Connection({
        // you can change loginUrl to connect to sandbox or prerelease env.
        loginUrl: 'https://www.salesforce.com'
    });

    return conn.login('some username', 'some password')
        .then(function(userInfo) { 
            // Now you can get the access token and instance URL information.
            // Save them to establish connection next time.
            console.log(conn.accessToken);
            console.log(conn.instanceUrl);
            // logged in user property
            console.log("User ID: " + userInfo.id);
            console.log("Org ID: " + userInfo.organizationId);
            // ...

            return conn.query("SELECT Id FROM anObject__c Where name = 'the name'")
        })
        .then(function(result){
              console.log("total : " + result.totalSize);
              console.log("fetched : " + result.records.length);
              // is returning the id
              console.log(result.records[0].Id);
              // the class that calls the methods saves it to a variable, the variable is undefined
              return result.records[0].Id;
        })
        .catch(function(err){
            console.error(err);
        });
}

Кажется, это работает, но возвращает обещание.

Суть асинхронного кода в том, что желаемого результата нет (пока), когда функция возвращает; поэтому вам нужно иметь дело с ценностью, которая будет доступна в какой-то момент в будущем.

Один из способов сделать это - вернуть Promise.

Возможно, вам стоит прочитать это: Как мне вернуть ответ из асинхронного вызова?

Похоже, что возвращаются 3 обещания или, по крайней мере, 3 значения, третье значение - это значение, которое мне нужно.

Нет, это просто цепочка обещаний. Может быть возвращено только одно значение, а также Promise может разрешаться только в одно значение; хотя это единственное значение может быть массивом.

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

Я не знаю, как получить доступ к этому значению.

нравится:

querySF().then(function(id){
    console.log("result: ", id);
});
person Thomas    schedule 23.05.2017
comment
Кажется, это работает, но возвращает обещание. Я отлаживал и вижу искомое значение, но не знаю, как получить к нему доступ. Похоже, что возвращаются 3 обещания или, по крайней мере, 3 значения, третье значение - это значение, которое мне нужно. - person Nicole Phillips; 23.05.2017
comment
@NicolePhillips, это querySF() не querrySF() - person Thomas; 24.05.2017
comment
Это была опечатка с моей стороны. У меня он указан как querySF () в классе js. - person Nicole Phillips; 24.05.2017
comment
Я обновил свой ответ, чтобы показать новую ошибку после использования вашего sln. - person Nicole Phillips; 24.05.2017
comment
Я отмечаю это как правильное, поскольку это отвечает на мой вопрос, однако я еще не понимаю обещаний, поэтому перешел в другой поток. Спасибо за вашу помощь. - person Nicole Phillips; 25.05.2017