2015-08-06 3 views
0

У меня есть фрагмент кода, который обрабатывает данные пользователя. Есть куча вложенных вызовов функции:Как обещает работать с вложенными вызовами функций

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 не ждет его!

+0

Да, каждая функция, которая делает что-то асинхронную и использует обещания (хотя бы иногда) должен всегда возвращать обещание. – Bergi

ответ

3

Это то, что вы эффективно делать в функции 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 Вернется неопределенными

Вот некоторый код свободно на основе кода, но она работает автономно чтобы продемонстрировать, как вы, возможно, должны делать вещи

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

Ну, я возвращаю 'validationResult' в' .then'. –

+0

да, но вы ничего не возвращаете в if if else, видите ли вы, как я сказал «ничего не возвращаю» ... это потому, что вы возвращаете что-либо в этом блоке кода. –

+0

Честно говоря, я не понимаю. Не выполняется ли 'then' часть? –

Смежные вопросы