Проблема с цепочкой обещаний узла js

#javascript #node.js #promise #salesforce #jsforce

#javascript #node.js #обещание #salesforce #jsforce

Вопрос:

Я пытаюсь подключиться к системе Salesforce с помощью библиотеки node js / jsforce и использовать обещания. К сожалению, один из методов выполняется до получения соединения.

у меня есть метод A: makeconnection, который возвращает соединение, у меня есть метод B: который загружает данные из Salesforce на основе ссылки на соединение из метода A, у меня есть метод C: который получает зависимости от Salesforce на основе соединения из метода A

Я бы хотел, чтобы был выполнен следующий порядок A ==> B ==> C

К сожалению, C, похоже, запускается первым, за которым следуют A и B, поэтому соединение равно нулю и оно завершается сбоем

примерно так выглядит код

 let jsforce = require("jsforce");
const sfdcSoup = require("sfdc-soup");
const fs = require("fs");
let _ = require("lodash");
let trgarr = [];
let clsarr = [];
let entityarr = [];

function makeConnection() {


  return new Promise((resolve,reject) => {
     const conn = new jsforce.Connection({
          loginUrl: "https://test.salesforce.com",
          instanceUrl: "salesforce.com",
          serverUrl: "xxx",
          version: "50.0"
        });

      
        conn.login(username, password, function (err, userInfo) {
          if (err) {
            return console.error(err);
          }
      
          // console.log(conn.accessToken);
          //console.log(conn.instanceUrl);
      
          //console.log("User ID: "   userInfo.id);
          //console.log("Org ID: "   userInfo.organizationId);
          console.log("logged in");
        });  
         resolve(conn);
   });
}

function loadClasses(conn) {

  return new Promise((resolve,reject) => {
     const querystr =
     "select apiVersion,name,body from apexClass where NamespacePrefix = null";
 
   let query = conn
     .query(querystr)
     .on("record", function (rec) {
       clsarr.push(rec);
     })
     .on("end", function () {
       console.log("number of class is "   clsarr.length);
       console.log("loaded all classes");
     });  
     resolve(conn,clsarr);
  });
}

async function getDependencies(conn) {




   return new Promise((resolve,reject) => {


     let entryPoint = {
          name: "xxx",
          type: "CustomField",
          id: yyy
        };
     
     let connection = {
          token: conn.accessToken,
          url: "abc.com",
          apiVersion: "50.0"
        };

       let usageApi =  sfdcSoup.usageApi(connection, entryPoint);

        usageApi.getUsage().then((response) => {
          console.log(response.stats);
          console.log(response.csv);

        });

   });

}
async function run() {
 makeConnection().then(conn => loadClasses(conn)).then(conn=>getDependencies(conn));
}

run();


 

Я продолжаю получать сообщение об ошибке с надписью UnhandledPromiseRejectionWarning: Ошибка: для объекта подключения требуются токен доступа и URL-адрес

Причина в том, что соединение должно быть получено из метода A и отправлено в метод C, чего не происходит. Не могли бы вы указать, где я могу ошибаться?

Также почему метод C выполняется перед A и B. почему моя цепочка обещаний не работает, как было обещано?

Я запускаю код в Vscode и использую узел 14

Комментарии:

1. Пожалуйста, поделитесь своим кодом

Ответ №1:

Ваш метод 2 имеет незначительную коррекцию первого метода makeConnection , разрешение должно быть внутри login после console.log("logged in")

И, во-вторых loadClasses , разрешение должно быть внутри события ‘end’. Пожалуйста, проверьте ниже 2 метода.

 function makeConnection() {
  return new Promise((resolve,reject) => {
     const conn = new jsforce.Connection({
          loginUrl: "https://test.salesforce.com",
          instanceUrl: "salesforce.com",
          serverUrl: "xxx",
          version: "50.0"
        });
      
        conn.login(username, password, function (err, userInfo) {
          if (err) {
            return console.error(err);
          }
      
          // console.log(conn.accessToken);
          //console.log(conn.instanceUrl);
      
          //console.log("User ID: "   userInfo.id);
          //console.log("Org ID: "   userInfo.organizationId);
          console.log("logged in");
          resolve(conn);
        });  
         
   });
}

function loadClasses(conn) {

  return new Promise((resolve,reject) => {
     const querystr =
     "select apiVersion,name,body from apexClass where NamespacePrefix = null";
 
     let query = conn
     .query(querystr)
     .on("record", function (rec) {
       clsarr.push(rec);
     })
     .on("end", function () {
       console.log("number of class is "   clsarr.length);
       console.log("loaded all classes");
       resolve(conn,clsarr);
     });  
     
  });
}
 

Ответ №2:

вы должны использовать серию обещаний, если методы зависят друг от друга, если методы не зависят, тогда вам следует использовать параллельный promise. ПОДРОБНЕЕ О СЕРИИ И ПАРАЛЛЕЛИ ОБЕЩАНИЙ.