我如何在Promise内返回状态?

IT技术 javascript node.js promise loopbackjs
2021-01-15 04:00:25

开始用loopback和jsforce学习promise,解决不了这个问题;我无法在Promise中将状态变量返回给 cb() 函数。基本上我想连接 salesforce 并通过 JSforce 获取数据并通过环回将其写入数据库。然后想在远程调用后将创建/更新/错误记录返回给客户端。

我正在通过使用 Node.JS 和 Express.js 开发 Loopback 我正在使用 JSforce 库来连接 salesforce

我该如何解决?

这是我的代码:

module.exports = function(Contact) {
  var jsforce = require('jsforce');
  var async = require("async");
  var lr = require('lr.js');

  Contact.ImportContacts = function(cb) {
    // Salesforce Projects List
    var sf_projects = [];
    //Salesforce Conn String
    var conn = lr.SalesforceConn();
    conn.apex.get("/Contact/", function(err, res) {
      var status = {
        "Created": [],
        "Updated": [],
        "Error": ""
      };
      if (err) console.log(err);

      sf_projects = res;
      // Clear result
      status.Created.length = 0;
      status.Updated.length = 0;
      status.Error = "";

      if (sf_projects != undefined) {
        async.eachSeries(sf_projects, function(contact, callback) {
          Contact.findOrCreate({
              where: {
                co_SalesforceID: contact.Id
              }
            }, {
              co_Name: contact.FirstName,
              co_Surname: contact.LastName,
              co_Salutation: contact.Salutation,
              co_Title: contact.Title,
              co_Department: contact.Department,
              co_Email: contact.Email,
              co_PhonePersonal: contact.HomePhone,
              co_PhoneWork: contact.Phone,
              co_PhoneCell: contact.MobilePhone,
              co_Description: contact.Description,
              co_SalesforceID: contact.Id
            },
            function(err, cntct, created) {
              if (err) console.log(err);
              if (created) {
                status.Created.push(cntct.id);
                console.log("Contact created. SalesForeID: " +
                  cntct.co_SalesforceID +
                  " ContactName: " +
                  lr.isDefined(cntct.co_Salutation) + " " +
                  lr.isDefined(cntct.co_Name) + " " +
                  lr.isDefined(cntct.co_Surname));
              } else {
                Contact.replaceById(cntct.id, {
                    co_Name: contact.FirstName,
                    co_Surname: contact.LastName,
                    co_Salutation: contact.Salutation,
                    co_Title: contact.Title,
                    co_Department: contact.Department,
                    co_Email: contact.Email,
                    co_PhonePersonal: contact.HomePhone,
                    co_PhoneWork: contact.Phone,
                    co_PhoneCell: contact.MobilePhone,
                    co_Description: contact.Description,
                    co_SalesforceID: contact.Id
                  },
                  false,
                  function(err, obj) {
                    if (err) console.log(err);
                    status.Updated.push(obj.id);
                    console.log("Contact updated. SalesForeID: " +
                      obj.co_SalesforceID + " ContactName: " +
                      lr.isDefined(obj.co_Salutation) + " " +
                      lr.isDefined(obj.co_Name) + " " +
                      lr.isDefined(obj.co_Surname));
                  });
              }
            });
          callback(err);
        }, function(err) {
          if (err) console.error(err);
        });
      } else {
        console.log("Salesforce Connection Error!");
        status.Error = "Salesforce Connection Error";
      }
      return Promise.resolve(status);
    }).then(function(end) {
      cb(null, end);

    }).catch(function(err) {
      if (err) console.log(err);
    });
  };
  Contact.remoteMethod(
    'ImportContacts', {
      returns: {
        arg: 'result',
        type: 'string'
      },
      http: {
        path: '/importContacts',
        verb: 'get'
      }
    }
  );
};
1个回答

不完全清楚在询问什么,并且您没有包含在solve()这里可能很重要的功能,因此我只能给您一些一般提示。

你有这样的事情:

}).then(function(end) {
  cb(null, end);
}).catch(function(err) {
  if (err) console.log(err);
});

第一部分 ( then) 表明cb()回调将错误作为第一个参数,将值作为第二个参数,遵循 Node 回调的通常约定。

但是在第二部分 ( catch) 中,您不会调用带有错误的回调。此外,这if (err)是多余的,因为在catch处理程序中总会有一个错误,除非solve()函数返回一个被拒绝的Promisefalsenull指定为拒绝原因 - 即便如此,无论拒绝原因是什么,回调应该总是在这种情况下被调用错误:

}).then(function(end) {
  cb(null, end);
}).catch(function(err) {
  console.log(err);
  cb(err);
});

这样你就不会遇到回调永远不会被调用并永远等待的情况。当您将 promise 与传统回调混合使用时,您必须牢记以下几点:

任何将回调作为参数的函数都应确保调用此回调并且只调用一次。这是您作为函数作者的责任来确保这一点。如果出现错误,您应该运行:

callback(error);

如果成功,您应该致电:

callback(null, data);

这样,callback通过测试它的第一个参数,就可以知道操作何时完成以及它是成功还是失败:

function (err, data) {
  if (err) {
    console.log('Error:', err);
  } else {
    console.log('Success:', data);
  }
}

回调函数的整个调用通常是:

functionTakingCallback('some', 'arguments', function (err, data) {
  if (err) {
    console.log('Error:', err);
  } else {
    console.log('Success:', data);
  }
});

另一方面,如果函数返回一个promise,你可以像这样使用它:

functionReturningPromise('some', 'arguments')
.then(function (data) {
  console.log('Success:', data);
})
.catch(function (err) {
  console.log('Error:', err);
});

err在这种情况下不需要测试

回调应该总是被调用一次。Promises 应该总是最终被解决或拒绝。用法不同,调用者和被调用者的责任不同。当你混合这两种风格时——采用传统 Node 风格回调的函数和返回 promise 的函数——那么你必须小心这些差异。

有时,您可以将采用回调的函数转换为使用 Bluebird 及其类库等返回Promise的函数,promisify()promisifyAll()为整个代码库中的所有异步函数提供一致的 API。看:

您可以看到一些其他答案,其中我解释了回调和Promise之间的区别以及如何更详细地将它们一起使用,在这种情况下可能对您有所帮助:

嗨@rsp 感谢有关错误控制和回调的用法。我已经添加了丢失的代码,抱歉:/ 在返回时更改了一些代码。解决 => Promise.resolve 我将更改代码并立即尝试
2021-04-07 04:00:25