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

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

问题描述

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

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& Express.js
我正在使用JSforce库来连接salesforce

I'm developing with Loopback via using Node.JS & Express.js I'm using JSforce library to connect salesforce

我该如何解决这个问题?

How can I fix that?

这是我的代码:

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);
});

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

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(错误)是多余的,因为在 catch 处理程序中总会出现错误,除非 solve()函数返回被拒绝的承诺,其中 false null 指定为拒绝原因 - 即使这样,无论拒绝原因是什么,在错误的情况下应始终调用回调:

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);
});

这样你就不会遇到永远不会调用回调并永远等待的情况。当你将promises与传统的回调混合时,你必须记住一些事情:

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);

如果成功,您应致电:

callback(null, data);

这样,回调可以知道何时通过测试第一个参数,操作完成以及是否成功完成:

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);
  }
});

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

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);
});

在这种情况下无需测试错误

No need for testing err in this case.

应始终只调用一次回调。承诺应该总是最终解决或拒绝。用法不同,呼叫者和被呼叫者的责任也不同。当你混合这两种样式 - 采用传统节点式回调的函数和返回承诺的函数 - 那么你必须小心这些差异。

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:

  • http://bluebirdjs.com/docs/api/promise.promisify.html
  • http://bluebirdjs.com/docs/api/promise.promisifyall.html

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

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:

  • A detailed explanation on how to use callbacks and promises
  • Explanation on how to use promises in complex request handlers
  • An explanation of what a promise really is, on the example of AJAX requests

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

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