我如何返回承诺内的状态?
我开始学习使用loopback和jsforce的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'
}
}
);
};
这并不是完全清楚什么是问,你不包括你的solve()
函数在这里可能很重要,所以我只能给你一些一般的提示。
你有这样的事情:
}).then(function(end) {
cb(null, end);
}).catch(function(err) {
if (err) console.log(err);
});
第一部分( then
)建议cb()
回调将错误作为第一个参数,并将值作为第二个参数,遵循通常的节点回调约定。
但在第二部分( catch
)中,您不会将该错误称为回调。 此外, if (err)
是多余的,因为在catch
处理程序中总会有一个错误,除非solve()
函数返回被拒绝的承诺,其中指定false
或null
作为拒绝原因 - 即使如此,无论拒绝原因是什么,在出现错误时应始终调用回调函数:
}).then(function(end) {
cb(null, end);
}).catch(function(err) {
console.log(err);
cb(err);
});
这样你就不会得到回调永远不会被调用并且一直等待的情况。 当你将承诺与传统回调混合使用时,你必须牢记几件事:
任何将回调作为参数的函数都应确保调用该回调函数,并且该函数只被调用一次。 这是您作为功能作者确保的责任。 在发生错误的情况下,您应该运行:
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);
}
});
另一方面,如果函数返回一个承诺,则可以这样使用它:
functionReturningPromise('some', 'arguments')
.then(function (data) {
console.log('Success:', data);
})
.catch(function (err) {
console.log('Error:', err);
});
在这种情况下不需要测试err
。
回调应该总是被调用一次。 承诺总是应该最终解决或拒绝。 用法不同,主叫方和被叫方的责任是不同的。 当你将这两种风格混合在一起时 - 那些采用传统的节点式回调函数和返回承诺的函数 - 那么你必须小心这些差异。
您有时可以将使用回调的函数转换为使用Bluebird及其promisify()
和promisifyAll()
等库来返回promise的函数,以便为您的整个代码库中的所有异步函数提供一致的API。 看到:
您可以在其中解释回调和承诺之间的区别以及如何更详细地使用它们,这可能对您有所帮助: