Как я могу вернуть статус внутри обещания?
Я начал изучать обещание с loopback и jsforce и не мог справиться с этой проблемой; Я не мог вернуть статусную переменную внутри обещания функции cb(). В основном я хочу подключить salesforce и получить данные через JSforce и записать их в базу данных через обратную связь. Затем хотите вернуть созданные / обновленные / записи об ошибках клиенту после удаленного вызова.
Я разрабатываю с помощью Loopback с помощью Node.JS & Express.js. Я использую библиотеку 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()
callback принимает ошибку в качестве первого аргумента и значение в качестве второго аргумента, следуя обычному соглашению обратных вызовов Node.
Но тогда во второй части (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
в этом случае.
Обратные вызовы всегда должны вызываться ровно один раз. Обещания всегда должны быть либо выполнены, либо в конечном итоге отклонены. Использование отличается, и ответственность звонящего и вызываемого абонента различна. Когда вы смешиваете эти два стиля - функции, которые принимают традиционные функции обратного вызова в стиле Node, и функции, которые возвращают обещания, - вы должны быть осторожны с этими различиями.
Иногда вы можете конвертировать функции, которые принимают обратные вызовы, в функции, которые возвращают обещания, используя такие библиотеки, как Bluebird и его promisify()
а также promisifyAll()
иметь согласованный API для всех ваших асинхронных функций во всей вашей кодовой базе. Увидеть:
- http://bluebirdjs.com/docs/api/promise.promisify.html
- http://bluebirdjs.com/docs/api/promise.promisifyall.html
Вы можете увидеть некоторые другие ответы, в которых я объясню разницу между обратными вызовами и обещаниями и как их использовать более подробно, что может быть полезно для вас в этом случае: