2016-12-03 8 views
0

Я часто слышал описание использования Deferred как «анти-шаблон» (например, here). Я пытаюсь понять, есть ли у меня сценарий, когда использование отложенного имеет смысл, может быть, вы можете помочь. У меня есть recaptcha на странице одностраничного веб-приложения. Чтобы выполнить определенные действия, нужно пройти тест на капчу. Поскольку срок действия капчеи истекает через некоторое время, пользователю может потребоваться повторить тест. Но в других случаях пользователь может инициировать одно из этих действий до истечения срока действия кода, поэтому он не должен повторять тест. Здесь ниже некоторого псевдокода, чтобы лучше понять:Является ли это хорошим вариантом для отсрочки?

class App { 
    constructor() { 
    this.captchaPromise = new Deferred(); 
    } 

    maybeDoIt() { 
    this.captchaPromise.then(() => { 
     this._doIt(); 
    }) 
    } 

    _doIt() { 
    alert('done'); 
    } 

    _onCaptchaSuccess() { 
    this.captchaPromise.resolve(); 
    } 

    _onCaptchaExpire() { 
    this.captchaPromise.reject(); 
    this.captchaPromise = new Deferred(); 
    } 
} 

const app = new App(); 

window._captchaOnload = function() { 
    window.grecaptcha.render('js-captcha', { 
    'sitekey': 'dsadaablsabllbalblablalblablablalbalbalblablabla31', 
    'callback': app._onCaptchaSuccess.bind(app), 
    'expired-callback': app._onCaptchaExpire.bind(app) 
    }); 
}; 

Как вы думаете, это хороший способ реализации выше сценария?

Я также пытаюсь найти отложенную реализацию или библиотеку vanilla js, которая поддерживает синтаксис импорта модуля es6 и поддерживает хотя бы IE9 и выше, даже IE8 будет отличным (я не могу использовать jQuery). Любая помощь очень ценится.

Update:

спасибо за ваш ответ, в конце концов, я решил, что мне не нужно обещание вообще. Однако, чтобы обещать рекапш-рендер, это была хорошая идея. Я решил сделать следующее:

_doIt (data) { 
    if (!this._captchaSolved) { 
     this._dataToUseAfterCaptchaSuccess = data; 
     return; 
    } 
    this._dataToUseAfterCaptchaSuccess = null; 

    console.log('done', data); 
    } 

    _onCaptchaSuccess (captchaResponse) { 
    this._captchaSolved = true; 
    this._captchaResponse = captchaResponse; 

    if (this._dataToUseAfterCaptchaSuccess) { 
     this._doIt(this._dataToUseAfterCaptchaSuccess); 
    } 
    } 

    _onCaptchaExpire() { 
    this._captchaSolved = false; 
    } 

ответ

0

Насколько я могу судить, отсрочка не требуется.

Как написано, он делает две вещи, оба из которых могут быть достигнуты более просто:

  • в качестве индикатора состояния: «в ожидании» фактически означает «непредвиденного» и «отверг» означает "истек. Вместо этого можно было бы использовать простой Boolean.
  • как способ вызова _doIt(): который может быть вызван непосредственно из обработчика _onCaptchaSuccess или даже указан как обработчик обратного вызова .render.

Более реалистичный подход будет promisify window.grecaptcha.render(), например, следующим образом:

window._captchaOnload = function() { 
    new Promise(function(resolve, reject) { 
     window.grecaptcha.render('js-captcha', { 
      'sitekey': 'dsadaablsabllbalblablalblablablalbalbalblablabla31', 
      'callback': resolve, 
      'expired-callback': reject 
     }); 
    }) 
    .then(app._doIt.bind(app), app.expire.bind(app)); 
}; 

app должен быть написано соответственно, не связанным с Deferreds или обещание.

+0

Спасибо @ Roamer-1888! Я обновил свой вопрос с помощью решения, которое я использовал – kuus