#javascript #node.js #amazon-web-services #amazon-cognito
Вопрос:
После экспорта необходимых модулей и настройки переменных
let AWS = require("aws-sdk");
const AmazonCognitoIdentity = require('amazon-cognito-identity-js');
const USER_POOL_ID = 'us-east-1_vkXRQuP4U';
const CLIENT_ID = 'mipa4trls0l7323om33mlk80e8';
const poolData = {
UserPoolId : USER_POOL_ID, ClientId : CLIENT_ID
};
const POOL = new AmazonCognitoIdentity.CognitoUserPool(poolData);
let email = "my.email@domain.com";
let password = "My.Password!";
Я могу продолжить и вызвать signUp
команду:
POOL.signUp(email, password, [], null, function(err, result) {
console.log('...result:', result);
});
И это хорошо работает. Затем я хочу обернуть POOL.signUp(email, password...)
внутреннюю async
функцию sign_up
следующим образом:
async function sign_up(email, password) {
POOL.signUp(email, password, [], null, function(err, result) {
console.log('...sign_up.result:', result);
return resu<
})
};
async function main() {
let signupData = await sign_up(email, password);
console.log('...main.signupData:', signupData);
return signupData;
};
main().then((error, data) => {console.log('...error, data:', error, data)});
Хотя это работает нормально, порядок выполняемых вызовов неверен, так как main
функция не ждет завершения sign_up()
функции. В попытке исправить такое поведение я заворачиваю POOL.signUp(email, password...)
внутри обещание:
async function sign_up(email, password) {
return await new Promise((resolve) => {
POOL.signUp(email, password, [], null, {
onSuccess: (result) => {
console.log('...result:', result)
return resolve(result);
},
onFailure: (err) => {
return resolve(err.message);
},
});
})
};
Но я получаю сообщение об ошибке:
UnhandledPromiseRejectionWarning: TypeError: callback is not a function
Есть ли способ избежать этой ошибки?
Ответ №1:
- не нужно
await
обещать, что вы возвращаете (поскольку мы точно хотим, чтобы наша функция была асинхронной, мы хотим отложить ожидание до вызывающего абонента) Promise
функция конструктора должна предоставить второйreject
параметр, чтобы иметь возможность доступа к обратному вызову в реализации функции- передайте функцию обратного вызова в качестве
POOL.signUp
четвертого аргумента вместо объекта
function sign_up(email, password) {
return new Promise((resolve, reject) => {
POOL.signUp(email, password, [], null, function(err, result) {
if (err) {
return reject(err.message);
}
console.log('...result:', result)
resolve(result);
});
})
};
Комментарии:
1. Я удалил функцию
async
— функция, которая возвращает обещание напрямую, в ней не нуждается. Также возвращение послеreject()
-хорошая идея.2. Ценю правку. Я забыл о возврате в потоке управления, я переместил его так, чтобы он просто возвращал результат отклонения вызова (по стилистическим соображениям).
3. Что ж, в таком случае
if (err) return reject(err.message);
это еще более ловко. 🙂4. Возможно, это самое элегантное решение для node.js это
const { promisify } = require('util');
и.POOL.signUpAsync = promisify(POOL.signUp);
Нет необходимости обещать функции вручную.5. Когда операция действительно заинтересуется, они узнают об этом из комментариев.