我如何在承诺内返回状态? [英] How can i return status inside the promise?

查看:17
本文介绍了我如何在承诺内返回状态?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I started to learning promise with loopback and jsforce, and couldn't handle this problem; I couldn't return status var inside promise to cb() function. Basically i want to connect salesforce and get data via JSforce and write it to db via loopback. Then want to return created/updated/error records to client after remote mothed called.

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

I'm developing with Loopback via using Node.JS & Express.js I'm using JSforce library to connect 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'
      }
    }
  );
};

推荐答案

不完全清楚在询问什么,并且您没有包含您的 solve() 函数,这在这里可能很重要,所以我只能给你一些一般的提示.

It's not entirely clear what are asking about, and you don't include your solve() function which may be important here, so I can only give you some general tips.

你有这样的事情:

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

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

The first part (then) suggests that the cb() callback takes the error as the first argument and a value as the second argument, following the usual convention of Node callbacks.

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

But then in the second part (catch) you don't call the callback with the error. Also, the if (err) is redundant since in the catch handler there will always be an error, unless the solve() function returns a rejected promise with false or null specified as the rejection reason - and even then, whatever the rejection reason is, the callback should always be called in the case of error:

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

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

That way you will not get a situation where the callback is never called and waits forever. When you mix promises with traditional callbacks you have to keep few things in mind:

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

Any function that gets a callback as an argument should make sure that this callback is called and that it is called exactly once. This is your responsibility as the function author to ensure that. In the case of error you should run:

callback(error);

如果成功,您应该调用:

and in the case of success you should call:

callback(null, data);

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

That way, the callback can know when the operation is finished and whether it finished with a success or failure by testing its first argument:

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

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

The entire invocation of a function taking callback is usually:

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

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

On the other hand if the function returns a promise, you use it like this:

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

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

No need for testing err in this case.

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

Callbacks should always be called exactly once. Promises should always be either resolved or rejected eventually. The usage is different and the responsibility of both the caller and the callee is different. When you mix those two styles - functions that take traditional Node-style callbacks and functions that return promises - then you have to be careful with those differences.

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

You can sometimes convert functions that take callbacks to functions that return promises using libraries like Bluebird and its promisify() and promisifyAll() to have consistent API for all your async functions in your entire code base. See:

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

You can see some other answers where I explain the difference between callbacks and promises and how to use them together in more detail, which may be helpful to you in this case:

这篇关于我如何在承诺内返回状态?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆