[英]How promise works with nested function calls
I have a piece of code which deals with user's data. 我有一段处理用户数据的代码。 There are bunch of nested function calls : 有很多嵌套函数调用:
f1(){
f2(){
....
fn{
///
}
}
}
fn
accesses a database which means it's asynchronous, so I wrote it somehow that it returns a promise
and in fn-1
(the function which calls fn
) , we use .then()
to wait for this promise. fn
访问一个数据库,这意味着它是异步的,因此我以某种方式编写了它以返回一个promise
并且在fn-1
(调用fn
的函数)中,我们使用.then()
等待该诺言。 But it looks like now I have to return a promise in fn-1
and so on. 但是看起来现在我必须在fn-1
返回一个promise,依此类推。 Is that true ? 真的吗 ?
var keyValueExists = function(key, value) {
var query = {};
query[key] = value;
return new Promise(function(resolve, reject) {
User.count(query, function(err, count) {
if (err) {
console.log(err);
console.log('Problem with `.find` function');
reject('Problem with `.find` function');
} else {
resolve(count !== 0);
}
});
});
};
var addUser = function(newUserInfo) {
var validationResult = Common._validateUserInfo(newUserInfo);
if (validationResult.isOK) {
keyValueExists('userName', newUserInfo.userName).then(function(userNameAlreadyExists) {
if (userNameAlreadyExists) {
validationResult = {
isOK: false,
reason: 'Username already exists',
infoWithBadInput: 'userName'
}
} else {
var newUserId = generateUserId();
//TODO: change it somehting more flexible. e.g. a predefined list of attributes to iterate over
var newUser = {
'userName': newUserInfo.userName,
'password': newUserInfo.password,
'userId': newUserId,
'lastModificationTime': Common.getCurrentFormanttedTime(),
'createdTime': Common.getCurrentFormanttedTime()
};
var user = new User(newUser);
user.save(function(err) {
if (err) {
console.log(err);
console.log('There is a problem saving the user info');
} else {
console.log('A new user added: ');
console.log(newUser);
}
});
}
return validationResult;
});
} else {
return validationResult;
}
};
addUser returns undefined
! addUser返回undefined
! It looks like that the caller of addUser
doesn't wait for it ! 看来addUser
的调用者没有等待它!
This is what you are effectively doing in your addUser function 这是您在addUser函数中有效执行的操作
var addUser = function(newUserInfo) {
var validationResult = Common._validateUserInfo(newUserInfo);
if (validationResult.isOK) {
// ... do something asynchronously without returning anything
} else {
return validationResult;
}
}
So, yeah, if validationResult.isOK
, adduser WILL return undefined 所以,是的,如果validationResult.isOK
,adduser将返回未定义
Here's some code loosely based on your code, but it runs standalone to demonstrate how you possibly should be doing things 这是一些基于您的代码的松散代码,但是它可以独立运行以演示您应该如何做
var keyValueExists = function(key, value) {
// pseudo junk, this simulates any username starting with b as existing
return new Promise(function(resolve, reject) {
resolve(value.substr(0,1) == 'b'); // barny and betty are dupes, fred and wilma are not
});
}
var addUser = function (newUserInfo) {
// var validationResult = Common._validateUserInfo(newUserInfo);
var validationResult = {isOK: !!~(['fred', 'barny'].indexOf(newUserInfo.userName)), username: newUserInfo.userName}; // dummy code
if (validationResult.isOK) {
return keyValueExists('userName', newUserInfo.userName).then(function (userNameAlreadyExists) {
if (userNameAlreadyExists) {
validationResult = {
isOK: false,
reason: 'Username already exists',
infoWithBadInput: 'userName',
username: newUserInfo.userName
}
} else {
// create new user here
validationResult.userNumber = (Math.random() * 100000000) | 0;
}
return validationResult;
});
}
else {
// this function always needs to return a promise, even if it is resolved/rejected immediately
return Promise.reject(validationResult);
}
}
addUser({userName: 'fred'}).then(function (result) {
console.log(result);
}).catch(function(err) {
console.error(err);
});
addUser({userName: 'wilma'}).then(function (result) {
console.log(result);
}).catch(function(err) {
console.error(err);
});
addUser({userName: 'barny'}).then(function (result) {
console.log(result);
}).catch(function(err) {
console.error(err);
});
addUser({userName: 'betty'}).then(function (result) {
console.log(result);
}).catch(function(err) {
console.error(err);
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.