我在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 .
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 });更多推荐
承诺:然后再解决
发布评论