Как вырваться из обещания (.then) заявления javascript - PullRequest
0 голосов
/ 01 июля 2019

У меня возникла проблема при попытке вырваться из оператора обещания при возникновении ошибки в операторе catch.

Я не уверен, что смогу выдать ошибку внутри оператора catch.

Проблема : функция catch ничего не делает, когда выдает ошибку.

Ожидаемый результат : для оператора catch для отображения предупрежденияи разорвать цепочку обещаний.

Код :

        if (IsEmail(email)) {
        $('body').loadingModal({
              position: 'auto',
              text: 'Signing you in, please wait...',
              color: '#fff',
              opacity: '0.9',
              backgroundColor: 'rgb(0,0,0)',
              animation: 'doubleBounce'
        });

        var delay = function(ms){ return new Promise(function(r) { setTimeout(r, ms) }) };
        var time = 2000;

        delay(time)
        .then(function() { $('body').loadingModal('animation', 'foldingCube'); return delay(time); } )
        .then(function() { 
            firebase.auth().signInWithEmailAndPassword(email, password)
            .then(function () {
                var user = firebase.auth().currentUser;
                uid = user.uid;
                configure();
            })
            .catch(function(error) {
                throw error;
            });
        })
        .then(function() { $('body').loadingModal('color', 'white').loadingModal('text', 'Welcome to Dtt deliveries').loadingModal('backgroundColor', 'orange');  return delay(time); } )
        .then(function() { $('body').loadingModal('hide'); return delay(time); } )
        .then(function() { $('body').loadingModal('destroy') ;} )
        .catch(function(error) {
            alert("Database error: " + error);
        }); 
    }
    else {
        alert("Please enter a valid email");
        return;
    }

1 Ответ

0 голосов
/ 01 июля 2019

Второй .then после delay разрешается немедленно, потому что с него ничего не возвращается. Вместо этого верните вызов signInWithEmailAndPassword, потому что он возвращает Обещание, которое вам нужно связать вместе с внешней цепочкой Обещания:

.then(function() {
  return firebase.auth().signInWithEmailAndPassword(email, password)
  // ...

Кроме того, перехват и немедленный бросок ничего не делают - если вам не нужно для обработки ошибки, специфичной для signInWithEmailAndPassword, не стесняйтесь опускать это catch полностью:

delay(time)
  .then(function() { $('body').loadingModal('animation', 'foldingCube'); return delay(time); } )
  .then(function() { 
    return firebase.auth().signInWithEmailAndPassword(email, password)
  })
  .then(function () {
    var user = firebase.auth().currentUser;
    uid = user.uid;
    configure(); // if configure returns a Promise, return this call from the `.then`
  })
  .then(
  // ...
  .catch(function(error) {
    alert("Database error: " + error);
  });

Если configure также возвращает Обещание, вам также нужно его вернуть. (если это синхронно, в этом нет необходимости)

(вы можете также рассмотреть возможность использования более удобного способа отображения ошибки, возможно, используйте правильный модальный тип вместо alert)

Другой вариант, который следует рассмотреть, - это использование await вместо всех этих .then s, поток управления может быть более четким:

(async () => {
  if (!IsEmail(email)) {
    alert("Please enter a valid email");
    return;
  }
  $('body').loadingModal({
    position: 'auto',
    text: 'Signing you in, please wait...',
    color: '#fff',
    opacity: '0.9',
    backgroundColor: 'rgb(0,0,0)',
    animation: 'doubleBounce'
  });

  var delay = function(ms) {
    return new Promise(function(r) {
      setTimeout(r, ms)
    })
  };
  var time = 2000;

  try {
    await delay(time);
    $('body').loadingModal('animation', 'foldingCube');
    await delay(time);
    await firebase.auth().signInWithEmailAndPassword(email, password)
    var user = firebase.auth().currentUser;
    uid = user.uid;
    configure(); // if this returns a Promise, `await` it
    $('body').loadingModal('color', 'white').loadingModal('text', 'Welcome to Dtt deliveries').loadingModal('backgroundColor', 'orange');
    await delay(time);
    $('body').loadingModal('hide');
    await delay(time);
    $('body').loadingModal('destroy');
  } catch(error) {
    alert("Database error: " + error);
  }
})();
...