Nativescript Vue - функция блокирует DOM - PullRequest
0 голосов
/ 28 февраля 2020

У меня есть приложение vue на нативном скрипте, и на определенной странице мне нужно извлечь некоторые данные (каждые 3 секунды) из API с помощью ax ios. Данные возвращаются в xml, и я конвертирую их в json, используя xml2 js. Я использую async / await для обеих этих функций. Что-то блокирует поток пользовательского интерфейса, потому что, когда эта функция запускается, прокрутка в моем приложении останавливается вместе с анимацией.

Кто-нибудь знает, что здесь блокирует DOM?

<template>
  //ui code here
</template>

<script>
import { mapGetters } from 'vuex'
import axios from 'axios'
import xml2js  from 'nativescript-xml2js'

export default {
  name: 'component1',
  data () {
    return {
      pending: true,
      error: false,
      results: null,
      refreshInterval: null
    }
  },
  computed: {
    ...mapGetters({
      token: 'main/token'
    })
  },
  methods: {
    async requestData() {

      const headers = {
        Cookie: 'USER_ID=' + this.token
      }
      const url = 'url goes here'
      const parser = new xml2js.Parser({
        async: true
      })

      try {
        const response = await axios.get(url, { headers: headers })

        const newData = await new Promise((resolve, reject) => parser.parseString(response.data, (err, result) => {
          if (err) reject(err)
          else resolve(result)
        }))

        this.results = newData['results']
        this.error = false
        this.pending = false

      } catch (e) {
        this.data = null
        this.error = e
        this.pending = false
      }
      this.pending = false
    }
  },
  created() {
    setTimeout(() => {
      this.requestData()
    },500)
    this.refreshInterval = setInterval(() => {
      this.requestData()
    },3000)
  },
  beforeDestroy () {
    clearInterval(this.refreshInterval)
  }
}
</script>

РЕДАКТИРОВАТЬ: Я пытался реализовать рабочих, чтобы разгрузить xml2 js в другой поток, но все еще та же проблема. Вот как выглядит мой код:

home. vue:

<template>
<template/>

<script>
import { mapGetters } from 'vuex'

export default {
  name: 'component1',
  data () {
    return {
      dataLoaded: true,
      error: false,
      results: null,
      refreshInterval: null
    }
  },
  computed: {
    ...mapGetters({
      token: 'main/token'
    })
  },
  methods: {
    requestData() {

      console.log('fetching....')

      this.$backendService
        .api()
        .then(xml => {
          return this.$backendService.x2jworker(xml)
        })
        .then(json => {
          if( this.results !== json['results'] ) {
            this.results  = json['results']
          }
          this.dataLoaded = true
          this.error = false
        })
        .catch((error) => {
          this.dataLoaded = true
          this.error = true
        })
    }
  },
  created() {
    setTimeout(() => {
      this.requestData()
    },500)
    this.refreshInterval = setInterval(() => {
      this.requestData()
    },3000)
  },
  beforeDestroy () {
    clearInterval(this.refreshInterval)
  }
}
</script>

backend-service. js:

import axios from 'axios';
import xml2js from 'nativescript-xml2js'
import { WorkerService } from "../worker.service"

export default class BackendService {

  api() {
    return new Promise((resolve, reject) => {
      const url = 'url'
      axios.get(url)
        .then(response => {
          resolve(response.data)
        })
        .catch((error) => {
          if (error) {
            console.log('uh oh')
            reject(error)
          }
        })
    })
  }

  x2jworker(xml) {
    return new Promise((resolve, reject) => {
      var workerService = new WorkerService()
      var jsWorker = workerService.initJsWorker()
      jsWorker.onmessage = m => {
        resolve(m.data)
      }
      jsWorker.postMessage(xml)
      jsWorker.onerror = e => {
        console.log(e)
        jsWorker.terminate()
        reject(e)
      }
    })
  }
}

worker / javascript .worker. js:

import 'tns-core-modules/globals'
import xml2js  from 'nativescript-xml2js'

global.onmessage = function (msg) {
    console.log("Inside JS worker...")
    var parser = new xml2js.Parser({
      async: true
    })

    parser.parseString(msg.data, function (err, result) {
      if (err) {
        console.log(err)
        global.close()
      } else {          
        global.postMessage(result)
      }
    })
}

работник-сервис. js:

const workers = []

export class WorkerService {
  constructor() {
  }

  initJsWorker() {
    if (this.jsWorker) {
      return this.jsWorker
    }

    const JsWorker = require("nativescript-worker-loader!./workers/javascript.worker.js")
    this.jsWorker = new JsWorker()
    workers.push(this.jsWorker)

    return this.jsWorker
  }
}

if ((module).hot) {
  (module).hot.dispose(() => {
    workers.forEach(w => {
      w.terminate()
    })
  })
}
...