承诺:然后再解决 [英] Promise: Then before Resolve

查看:61
本文介绍了承诺:然后再解决的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆