【问题标题】:How promise works with nested function callsPromise 如何与嵌套函数调用一起工作
【发布时间】:2015-08-06 12:59:21
【问题描述】:

我有一段处理用户数据的代码。有一堆嵌套的函数调用:

f1(){
   f2(){
     ....
      fn{
        ///
      }
   }
}

fn 访问一个数据库,这意味着它是异步的,所以我以某种方式写了它返回一个 promise 并在 fn-1(调用 fn 的函数)中,我们使用 .then() 等待这个承诺。但看起来现在我必须在fn-1 中返回一个承诺,依此类推。真的吗 ?

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 返回undefined !看起来addUser 的调用者没有等待它!

【问题讨论】:

  • 是的,每个执行异步操作并使用承诺(即使只是有时)的函数都需要始终返回一个承诺。

标签: javascript asynchronous promise


【解决方案1】:

这就是您在 addUser 函数中有效执行的操作

var addUser = function(newUserInfo) {
    var validationResult = Common._validateUserInfo(newUserInfo);
    if (validationResult.isOK) {
        // ... do something asynchronously without returning anything
    } else {
        return validationResult;
    }
}

所以,是的,如果validationResult.isOK,adduser 将返回 undefined

这里有一些大致基于您的代码的代码,但它独立运行以演示您应该如何做事

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);
});

【讨论】:

  • 好吧,我在.then 中返回validationResult
  • 是的,但是你没有在 if/else 的 if 部分返回任何东西,是吗 - 看看我怎么说“不返回任何东西”......那是因为你确实返回了任何东西在那个代码块中。
  • 老实说,我不明白。 then 部分不运行吗?
  • 是的,但是没有处理它的返回值
  • 所以在addUser中你没有定义任何Promise,调用的时候怎么把它当作一个promise呢?
猜你喜欢
  • 2020-03-26
  • 2020-06-27
  • 1970-01-01
  • 2023-01-10
  • 1970-01-01
  • 1970-01-01
  • 2020-09-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多