2016-12-03 50 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) 
    }); 
}; 

你覺得這是落實上述方案的好辦法?

我也在努力尋找一個支持es6模塊導入語法的vanilla js延遲實現或庫,並且支持至少IE9及更高版本,即使IE8會很棒(我無法使用jQuery)。任何幫助非常感謝。

更新:

謝謝你的回答,最後我決定,我並不需要一個承諾都沒有。儘管recartcha渲染是一個不錯的主意。我解決了以下幾點:

_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

據我所知,延期是沒有必要的。

作爲寫的,它完成兩件事情,這兩者可以更簡單地實現:

  • 作爲狀態指示器:「掛起」實際上意味着「未過期」和「拒絕」的意思是「過期」。可以使用簡單的布爾值代替。
  • 作爲調用_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

相關問題