我怎样才能返回承诺的状态?
我开始学习使用loopback和jsforce的承诺,并不能解决这个问题。 我不能返回状态var内的承诺cb()函数。 基本上我想连接salesforce并通过JSforce获取数据,并通过回送将其写入数据库。 然后想要远程调用返回创build/更新/错误logging到客户端。
我正在通过使用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' } } ); };
这并不是完全清楚什么是问,你不包括你的solve()
函数在这里可能很重要,所以我只能给你一些一般的提示。
你有这样的东西:
}).then(function(end) { cb(null, end); }).catch(function(err) { if (err) console.log(err); });
第一部分( then
)build议cb()
callback将错误作为第一个参数,将一个值作为第二个参数,遵循通常的Nodecallback约定。
但是,在第二部分( catch
)中,您不会调用带有错误的callback函数。 另外, if (err)
是多余的,因为在catch
处理程序中总是会有一个错误,除非solve()
函数返回一个被拒绝的promise,其中false
或null
指定为拒绝原因 – 即使如此,无论拒绝原因是什么,在出现错误时应始终调用callback函数:
}).then(function(end) { cb(null, end); }).catch(function(err) { console.log(err); cb(err); });
这样,你将不会得到一个callback永远不会被调用,永远等待的情况。 当你将承诺与传统的callback相结合时,你必须牢记几件事情:
任何获得callback作为参数的函数都应该确保这个callback函数被调用,并且它只被调用一次。 这是你作为function作者的责任,以确保这一点。 在出现错误的情况下,您应该运行:
callback(error);
如果成功,你应该打电话给:
callback(null, data);
这样, callback
可以知道操作何时完成,以及通过testing其第一个参数是否成功完成:
function (err, data) { if (err) { console.log('Error:', err); } else { console.log('Success:', data); } }
对callback函数的整个调用通常是:
functionTakingCallback('some', 'arguments', function (err, data) { if (err) { console.log('Error:', err); } else { console.log('Success:', data); } });
另一方面,如果该函数返回一个承诺,则可以这样使用它:
functionReturningPromise('some', 'arguments') .then(function (data) { console.log('Success:', data); }) .catch(function (err) { console.log('Error:', err); });
在这种情况下不需要testingerr
。
callback应该总是被调用一次。 承诺总是应该最终解决或拒绝。 使用方法不同,主叫方和被叫方的责任是不同的。 当你把这两种风格混合起来的时候 – 那些采用传统的Node风格的callback函数和返回promise的函数 – 那么你必须小心这些差异。
有时候可以将函数转换为函数,函数返回使用Bluebird及其promisify()
和promisifyAll()
函数库的函数,以便为整个代码库中的所有asynchronous函数提供一致的API。 看到:
- http://bluebirdjs.com/docs/api/promise.promisify.html
- http://bluebirdjs.com/docs/api/promise.promisifyall.html
您可以在其中解释callback和承诺之间的区别以及如何更详细地使用它们,在这种情况下可能对您有所帮助:
- 有关如何使用callback和承诺的详细说明
- 有关如何在复杂的请求处理程序中使用promise的说明
- 关于AJAX请求的例子,解释了什么是承诺