2014-10-02 4 views
1

Здесь говорится, что мы получили запрос на регистрацию пользователя, мы должны определить, является ли имя пользователя уже маркером (давайте просто предположим, что данные действительны), и если это так, на:Как разбить обещание в функции `then`

User 
    .getByName(name) 
    .then(function (user) { 
     // if user is not null, which means the username is already token 
     if (user !== null) return res.json({errorCode: 1001}) 
    }) 
    .then(function() { 
     // Oops, the previous return is captcha here 
     // how to break the promise and return the request 
     var user = new User({ 
      name: name 
     }) 
    }) 

Спасибо за помощь

ответ

0

Попробуйте, как показано ниже. Это правильный способ использовать обещания.

var when = require('when'); 


checkUser(name) 
    .then(function() { 
    var user = new User({ 
     name: name 
    }) 
    }, function (error) { 
    // handle error here 
    }) 
} 

var function checkUser(name){ 

    var deferred = when.defer(); 

    User.getByName(name,function(user){ 
    user === null ? 
     deferred.resolve() : deferred.reject(new Error('Username alreay token')) 
    }); 

    return deferred.promise; 
} 
+1

Ну, кто решает, что «правильно»? Вы могли бы просто вернуть Promise.resolve() и Promise.reject() - не нужно создавать отложенные, а затем разрешать их позже в синхронном процессе ... – CFrei

+1

@CFrei Я не вижу синхронного кода, но я согласен с тем, что код может быть улучшен, как возвращать 'resolve' и' reject', что сделает это хорошим примером для такой проблемы :) – jiananshi

+0

@klamtlne, хотя мне нравится ваше редактирование, я думаю, что он меняет идею ответа Вакаса Ахмеда. –

1

Чтобы избежать вызова на ваш второй then, вам нужно сделать первый then неудачу. Просто добавьте в качестве последней строки function(user) a throw 'User exists', а следующий then переходит в путь отклонения, который вы не установили.

Я признаю, что это уродливый подход, но это сработает! ;)

+1

Есть много уродливых подходов, и это их верх. Пожалуйста, дайте подходящий пример, чтобы решить эту проблему, кроме этого наихудшего подхода. –

+0

Его вопрос: как разбить обещание в функции 'then'. Я ответил на этот вопрос и показал ему, как это сделать. Я думаю, он достаточно умен, чтобы реорганизовать остальную часть кода после того, как он понял эту концепцию. :) – CFrei

+0

+1 спасибо за то, что вы показали правильный способ сломать обещание! – jiananshi

0

Если вы не можете решить свое обещание, вы должны отвергнуть:

User.getByName(name).then(function(existing) { 
    // If user already exists, we should return 
    // rejected promise with good rejection reason 
    if (existing !== null) return reject { 
     message: 'User already exists', 
     errorCode: 1001, 
     status: 403 
    }; 
    var user = new User({ 
     name: name 
    }); 
    // ... some staff .. 
    return user.save(); 
}).then(function(user) { 
    // ... some other staff ... 
    res.json(user); 
}).otherwise(function(err) { 
    // Something bad happened somewhere in the chain 
    res.status(err.status || 400).json({ 
     message: err.message 
     errorCode: err.errorCode 
    }); 
}) 

В моем примере я использую универсальный обработчик отказ послать ошибочный ответ клиенту, потому что мы должны послать что-то независимо от того, что произошло.

reject В моем примере это функция возврата отклоненных обещаний. Большинство библиотек с обещаниями имеют такую ​​функцию (например, when.reject, Q.reject), но вы можете заменить ее встроенным оператором throw.

+0

Я только что узнал, что «reject» можно использовать таким образом, в большинстве случаев он используется с deffered: 'deffered.reject()'. Но я задаюсь вопросом, могу ли я поймать отклонение в следующей функции 'then'. ('throw' абсолютно работает) – jiananshi

+0

@klamtlne' deffered.reject() 'отклоняет' 'deffered.promise', а' when.reject'/'Q.reject' создает новое отклоненное обещание. –

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