關於微信 setData 回調函數中的坑

最近在作錄音功能,需求大致是這樣的:點擊開始錄音按鈕,頁面狀態變爲錄音中,而後開始錄音。

不過偉大的測試同窗發現了一個問題:當快速的連續點擊開始錄音按鈕時,會觸發屢次開始錄音的事件,這樣在結束錄音時就仍然會有一個正在錄音中的標識,像這樣:javascript

clipboard.png

下面開始曲折的修復之路:

最開始的代碼是這樣的:java

Page({

  /**
   * 生命週期函數--監聽頁面加載
   */
  onLoad: function(options) {
    // 初始化錄音管理器
    this.recorderManager = wx.getRecorderManager()

    // 錄音開始事件
    this.recorderManager.onStart(() => {
      
    })
  },

  /**
   * 錄音按鈕點擊事件
   */
  tapRecordBtn: function() {
    this.setData({
      // 切換頁面顯示
    }, () => {
      // 開始錄音
      this.recorderManager.start({})
    })
  },
})

這時個人猜想是:頁面從新渲染以前,按鈕仍是顯示狀態,因此還能被點擊。
那既然這樣,就加個標識,在一次點擊以後,到頁面從新渲染以前,都不能再次點擊就行了,代碼以下:函數

Page({

  /**
   * 生命週期函數--監聽頁面加載
   */
  onLoad: function(options) {
    // 初始化錄音管理器
    this.recorderManager = wx.getRecorderManager()
    // 錄音開始按鈕點擊標識
    this.isRecordBtnClicked = false

    // 錄音開始事件
    this.recorderManager.onStart(() => {

    })
  },

  /**
   * 錄音按鈕點擊事件
   */
  tapRecordBtn: function() {
    // 若是錄音按鈕已被點擊(錄音即將開始),則不會再次觸發開始錄音事件
    if (this.isRecordBtnClicked) {
      return
    }
    this.isRecordBtnClicked = true

    this.setData({
      // 切換頁面顯示
    }, () => {
      this.isRecordBtnClicked = false
      // 開始錄音
      this.recorderManager.start({})
    })
  },
})

想法是好的,不過並無實現想要的效果。仍是能夠被屢次點擊。
因而在屢次實驗以後,改成以下的方式(可行):測試

Page({

  /**
   * 生命週期函數--監聽頁面加載
   */
  onLoad: function(options) {
    // 初始化錄音管理器
    this.recorderManager = wx.getRecorderManager()
    // 錄音開始按鈕點擊標識
    this.isRecordBtnClicked = false

    // 錄音開始事件
    this.recorderManager.onStart(() => {
      // 將錄音按鈕的點擊狀態在錄音開始時修改
      this.isRecordBtnClicked = false
    })
  },

  /**
   * 錄音按鈕點擊事件
   */
  tapRecordBtn: function() {
    // 若是錄音按鈕已被點擊(錄音即將開始),則不會再次觸發開始錄音事件
    if (this.isRecordBtnClicked) {
      return
    }
    this.isRecordBtnClicked = true

    this.setData({
      // 切換頁面顯示
    }, () => {
      // 開始錄音
      this.recorderManager.start({})
    })
  },

})

結論

將按鈕的點擊狀態在錄音開始事件中進行重置,就能夠解決這個問題了。
說一下最後驗證的結果:setData() 方法的回調函數並非在頁面從新渲染完以後才執行的,因此並不能以回調函數做爲一個明確的時間點來處理一些邏輯。而因爲recorderManager.onStart() 方法觸發時會有必定的延時,因此間接的解決了這個問題。this

相關文章
相關標籤/搜索