[英]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.