承诺:然后再解决 [英] Promise: Then before Resolve
问题描述
我在Node.js中做过的第一件事,我正在编写一个AWS Lambda函数,并且我想在执行其他任何操作之前检查User上的自定义属性是否具有值.因为我被告知Promises是同步处理异步方法的方法,所以我编写了函数:
Very first thing I've ever done in Node.js, I'm writing an AWS Lambda function, and I want to check whether a custom attribute on a User has a value before doing anything else. Since I'm told Promises are the way to handle asynchronous methods synchronously, I wrote the function:
var AWS = require('aws-sdk');
var s3 = new AWS.S3();
var cogId = new AWS.CognitoIdentityServiceProvider();
exports.handler = function (event, context) {
if (event != null)
{
var identityId = context.identity.cognitoIdentityId;
if (event.userId != null)
{
var userId = event.userId;
PromiseConfirmIdNotSet(userId)
.then(SetId(userId, identityId))
.catch();
}
}
context.done(null, 'Hello World'); // SUCCESS with message
};
function PromiseConfirmIdNotSet(userId)
{
console.log('Entering function');
return new Promise(function (resolve, reject) {
console.log('Entering Promise');
cogId.adminGetUser({
UserPoolId: myUserPool,
UserId: userId
},
function (err, data) {
console.log('err = ' + JSON.stringify(err));
console.log('data = ' + JSON.stringify(err));
if (data != null && data.UserAttributes.Name == null) {
console.log('Calling resolve');
resolve();
} else {
console.log('Calling reject');
reject();
}
});
});
console.log('Exiting Promise');
}
function SetId(userId, identityId)
{
cogId.updateUserAttributes();
}
但是,当我运行它时,控制台日志显示正在输入函数",然后显示正在输入承诺",然后执行将转到 SetId
,而无需调用 adminGetUser <中指定的回调/code>.
But when I run it, the console log shows "Entering function", then "Entering Promise", then the execution goes to SetId
without ever having called the callback specified in adminGetUser
.
如果在主流程完成后让调试器继续运行,最终我会从回调函数中获取日志,因此它最终会运行.
If I let the debugger continue after the main flow is done, eventually I do get the logs from the callback function, so it does eventually run.
为什么Promise会跳到当时没有调用 resolve
的那一时刻?
Why is the Promise skipping to the then without the resolve
ever getting called?
推荐答案
.然后
接受 function 作为参数.当你做
.then
accepts a function as an argument. When you do
PromiseConfirmIdNotSet(userId)
.then(SetId(userId, identityId))
.catch();
PromiseConfirmIdNotSet
被调用,并且同步, SetId
被调用,而解释器试图构造 Promise
函数传递给 .then
的链接.(但是 SetId
不返回函数)然后,此后, PromiseConfirmIdNotSet
的异步代码运行,并且 Promise
解析-这不是不是按照您想要的顺序.
PromiseConfirmIdNotSet
is called, and synchronously, SetId
is called, while the interpreter tries to construct a Promise
chain from the function passed to .then
. (But SetId
doesn't return a function) Then, after that, PromiseConfirmIdNotSet
's asynchronous code runs, and the Promise
resolves - which isn't in the order you want.
对其进行更改,以使 SetId
仅在 PromiseConfirmIdNotSet
返回的承诺解析后称为:
Change it so that SetId
is only called after the promise returned by PromiseConfirmIdNotSet
resolves:
PromiseConfirmIdNotSet(userId)
.then(() => SetId(userId, identityId))
.catch();
问题与原因相似
addEventListener('click', fn());
不起作用-您将其更改为,fn);
或,()=>fn());
.
doesn't work - you'd change it to , fn);
or , () => fn());
.
如果您还希望 context.done
仅在成功完成 SetId
之后出现,则将 context.done
调用放在.然后
:
If you additionally want context.done
to occur only after a successful SetId
, then put the context.done
call inside the .then
:
PromiseConfirmIdNotSet(userId)
.then(() => {
SetId(userId, identityId);
context.done(null, 'Hello World'); // SUCCESS with message
});
这篇关于承诺:然后再解决的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!