繁体   English   中英

Promise的then方法何时实现或被拒绝?

[英]When does a promise's then method become fulfilled or rejected?

promises中的then()方法返回一个promise。 一个承诺可以处于三种状态之一,待定,已实现或被拒绝。 但是,在创建承诺时,如果希望实现或拒绝承诺,则可以调用已解决但被拒绝的方法。 我找不到在then()方法中的函数上使用这些方法的方法。 当我尝试在then()链中间使用带回调的普通异步函数时,这给我带来了问题。 以下面的代码为例。

        User.findOne({
            where: {
                email: email
            }
        }).then(function(user){
            if(user){
                return done(null, false, req.flash('signupMessage', 'That email is already taken.'));
            }else{
                var user = User.build({ email: email });
                console.log("ONE");
                User.generateHash(password, function(err, hash){
                    console.log("TWO");
                    if(err){
                        return done(err);
                    }else{
                        user.password = hash;
                        var newUser = user.save();
                        return newUser;
                    }
                })
            }
        }, function(err){
            console.log("ERROR: ", err);
        }).then(function(newUser){
            console.log("THREE");
            return done(null, newUser);
        }, function(err){
            console.log("USER NOT CREATED: ", err);
        });

在这种情况下,User.findOne()返回一个Promise。 现在,用于此的控制台将打印三个。 异步被调用后,第二条then语句即被调用。 有没有办法在我通知已解决之前不调用第二个then语句。

(我知道这是修复几种不同方式的简单代码,我对第一条语句返回的promise为何以及何时实现的要求更加好奇。)

那么,什么情况是, findUser得到满足(而不是拒绝),所以在第一个参数的回调.then()所调用(而不是秒)。 .then()子句中,您console.log("ONE")并没有返回任何内容(因为您属于else {子句,并且只返回了createHash的回调,这对承诺的上下文。),因此实际上返回undefined

然后,下一个.then()调用,您得到console.log("THREE")

然后在将来的某个时候,您会从createHash调用回调,并获得console.log("TWO")

正确的方法是编写User.generateHash以便它也返回一个User.generateHash ,然后可以将其与User.generateHash链的其余部分链接起来,而不必在Promise回调中处理异步内容。

创建承诺时,如果希望实现或拒绝承诺,则可以调用已解决但被拒绝的方法。 我无法找到如何在then()方法中的函数上使用这些方法

当在promise上使用then方法时,您无权访问resolve / reject回调- then为您管理所有这些。 它确实返回新的promise,它将根据您的回调结果 (即其返回值)进行解析。 此返回值可以是一个将被自动吸收的承诺(当您用承诺解决时,它将自动兑现/拒绝该承诺的结果)。

这就是您在这里需要做的。 如果要在then回调中调用回调方法,则必须为其创建一个promise,然后可以return 最简单,最好的方法是事先使回调函数有效 ,但是您也可以使用Promise构造函数(在其中可以访问resolve / reject )。

    User.findOne({
        where: {
            email: email
        }
    }).then(function(user){
        if (user){
            throw new Error('That email is already taken.');
        } else {
            var user = User.build({ email: email });
            console.log("ONE");
            var promise = new Promise(function(resolve, reject) {
//                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                User.generateHash(password, function(err, hash){
                if (err) reject(err);
                else     resolve(hash);
            });
            return promise.then(function(hash) {
                console.log("TWO");
                user.password = hash;
                var newUser = user.save();
                return newUser;
            });
        }
    }).then(function(newUser){
        console.log("THREE");
        return done(null, newUser);
    }, function(err){
        console.log("ERROR: ", err);
        return done(null, false, req.flash('signupMessage', err.message));
    });

如果done()和User.generateHash()不返回promise,则没有理由等待该程序的第二级进入下一个then()块。

要解决此问题,或查看您的打印报表打印出三两,我会这样做

User.findOne({
    where: {
        email: email
    }
}).then(function(user){
    var promise;
    if(user){
        promise = done(null, false, req.flash('signupMessage', 'That email is already taken.'));
    }else{
        var user = User.build({ email: email });
        console.log("ONE");
        promise = User.generateHash(password, function(err, hash){
            return new Promise(function(resolve, reject){
                console.log("TWO");
                if(err){
                    reject(done(err));
                }else{
                    user.password = hash;
                    var newUser = user.save();
                    resolve(newUser);
                }
            });
        });
    }

    return promise;
}, function(err){
    console.log("ERROR: ", err);
}).then(function(newUser){
    console.log("THREE");
    return done(null, newUser);
}, function(err){
    console.log("USER NOT CREATED: ", err);
});

这样,第一个然后将在转到下一个then块之前等待promise解析,这意味着User.generateHash将必须在转到下一个then块之前解析,因为变量promise依赖于此。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM