0

I'm writing a react-native application that uses a bluetooth module. My goal is to make the scan/connect/discover function async, so that I can wait on it and manage the return value accordingly.

This is the code I have right now:

 async writeData(data) {
    this.store.dispatch({type: "START_LOADER"})

    await this.manager.isDeviceConnected(this.deviceId).then(res => {
      if (res) {
        const device = this.store.getState().store.device

        device.writeCharacteristicWithoutResponseForService(
          data.serviceId,
          data.charId,
          data.dataToWrite
        ).then(res => {
          this.store.dispatch({type: "SET_STATUS", payload: `${data.message}!\n`})
          this.store.dispatch({type: "STOP_LOADER"})
        }).catch(error => {
          this.store.dispatch({type: "SET_ERROR", payload: error.message})
          this.store.dispatch({type: "STOP_LOADER"})
        })

        return true
      } else {
        const timeout = setTimeout(() => {
          this.store.dispatch({type: "STOP_LOADER"})
          this.store.dispatch({type: "SET_ERROR", payload: 'Function timeout: device not found'})

          return
        }, 10000)

        this.manager.startDeviceScan(null, null, (error, device) => {
          if (error) {
            this.store.dispatch({type: "SET_ERROR", payload: error.message})
            return
          }

          if (device.id === this.deviceId) {
            clearTimeout(timeout)

            this.store.dispatch({type: "SET_STATUS", payload: "North Sense found, stopping device scan...\n"})
            this.store.dispatch({type: "SET_DEVICE", payload: device})

            this.manager.stopDeviceScan();

            device.connect().then((device) => {
              this.store.dispatch({type: "SET_STATUS", payload: "device is connected!\n"})
              return device.discoverAllServicesAndCharacteristics()
            }).then((device) => {
              device.writeCharacteristicWithoutResponseForService(
                data.serviceId,
                data.charId,
                data.dataToWrite
              ).then(res => {
                this.store.dispatch({type: "SET_STATUS", payload: `${data.message}!\n`})
                this.store.dispatch({type: "STOP_LOADER"})
              }).catch(error => {
                this.store.dispatch({type: "SET_ERROR", payload: error.message})
                this.store.dispatch({type: "STOP_LOADER"})
              })
            }).catch((error) => {
              this.store.dispatch({type: "SET_ERROR", payload: error.message})
              this.store.dispatch({type: "STOP_LOADER"})
            });
          }
        });
      }
    }).catch(error => {
      this.store.dispatch({type: "SET_ERROR", payload: error.message})
      return error
    })
  }

This code is inserted in the context of a class, so the way I use this function is the following:

  const blApi = new blApi(deviceId)

  console.log('1')
  blApi.writeData({
    serviceId: Config.SERVICE_ID,
    charId: Config.ADD_PROGRAM_CHAR_ID,
    dataToWrite: btoa(`4;${this.state.bearing};${Config.SENSING_LOCATION_INDEX}`),
    message: "Person has been successfully added.",
  })
  console.log('2')

The logs don't wait for the function to return, especially when the case of the timeout is triggered (in case the bluetooth device is not around) and the timeout expires after 10 seconds I would expect the function to wait those 10 seconds before continuing to the next line.

How can I fix this?

ste
  • 3,087
  • 5
  • 38
  • 73
  • 2
    Your `await` isn’t really useful. What is it that should be waiting for the `await` operand to finish? Currently, it’s nothing; the function just ends after the `await` expression has finished. Did you mean something like `return await …`? – Sebastian Simon Oct 27 '19 at 12:47
  • 1
    It looks like you're mixing up "traditional" Promise code with `async/await`. That's not *wrong*, but it would be cleaner to use one approach or the other. – Pointy Oct 27 '19 at 12:49
  • Try reading this https://medium.com/@rafaelvidaurre/truly-understanding-async-await-491dd580500e. Maybe you'll understand better. – Vishnudev Krishnadas Oct 27 '19 at 12:51
  • Usually async/await and then/catch are used separately. They are not complementary, consider using one. – Animus Oct 27 '19 at 12:58
  • @Animus While I [agree in general](https://stackoverflow.com/a/54387912/1048572), I think that [handling rejections with `then`/`catch` syntax](https://stackoverflow.com/questions/44663864/correct-try-catch-syntax-using-async-await) is sometimes preferable even in `async`/`await` code. – Bergi Oct 27 '19 at 16:09

0 Answers0