question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

try use Web Worker to load

See original GitHub issue

Hi,

I’m trying to use Web Worker to load dicom, because the page has some carton when load.

But I encounter a problem now.


//worker.js

//some code...

var loader

function loadWithUrls (links) {
  var fileType = null
  if (typeof links === 'string') {
    var array = links.split('.')
    fileType = array[array.length - 1].toLowerCase()
  }

  return new Promise((resolve, reject) => {
    if (fileType === 'zip') {
      axios.get(
        links, {
          responseType: 'blob',
          onDownloadProgress: e => self.postMessage({type: 'downloading', value: {loaded: e.loaded, total: e.total}})
        })
        .then(res => {
          self.postMessage({type: 'parseBegin'})
          return Promise.resolve(res.data)
        })
        .then(JSZip.loadAsync)
        .then(zip => {
          // console.log(zip, loader);
          let seriesContainer = []
          let fileArray = Object.keys(zip.files)
          let fileArrayLength = fileArray.length
          fileArray.forEach(item => {
            zip.file(item).async('arraybuffer')
              .then(buffer => this.loader.parse({ url: item, buffer }))
              .then(series => {
                seriesContainer.push(series)
                let seriesContainerLength = seriesContainer.length
                self.postMessage({type: 'parsing', value: {parsed: seriesContainerLength, total: fileArrayLength}})
                if (seriesContainerLength >= fileArrayLength) {
                  resolve(seriesContainer[0].mergeSeries(seriesContainer)[0])
                  loader = null
                }
              })
              .catch(e => reject(e))
          })
        })
        .catch(e => reject(e))
    } else {
      loader.load(links)
        .then(() => {
          resolve(loader.data[0].mergeSeries(loader.data)[0])
          loader = null
        })
        .catch(e => reject(e))
    }
  })
}

self.onmessage = ({data}) => {
  loader = new VolumeLoader(false, () => {
    return {
      update: (v, t, mode) => {
        if (mode === 'load') {
          self.postMessage({type: 'downloading', value: {loaded: v, total: t}})
          if (v / t === 1) self.postMessage({type: 'parseBegin'})
        } else {
          self.postMessage({type: 'parsing', value: {loaded: v, total: t}})
        }
      }
    }
  })

  loadWithUrls(data.links)
    .then(value => {
      // if (!value.stack[0].packed) {
      //   value.stack[0].prepare()
      //   value.stack[0].pack()
      // }
      self.postMessage({type: 'result', value})
    })
    .catch(value => self.postMessage({type: 'error', value}))
}


//index.js

//some code...

var wk = new Worker('./worker.js')

wk.postMessage({type, links})

wk.onmessage = ({data}) => {
      switch (data.type) {
        //some code...

        case 'result':
          console.log('result', data)
          resultFn(data.value)
          break
      }
}

In index.js I get the series data.But the series data lost all function include get/set.

I can’t new StackHelper use the series._stack[0] ( I also can’t get stack by series.stack[0] ).

So…, I want know how to restore function, or Is there a better way to do this?

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:5 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
NicolasRannoucommented, Jun 12, 2018

Yes, I see what you mean, it is just the way web workers work. You can not pass objects between the worker and the main thread. The expensive bit in term of time is the DICOM downloading, parsing then packing. So all that should happen in the WW as you are doing.

I think you may have to run one worker per file to be parsed but I am not too sure yet which is the best approach.

But I agree with you that it is the way to go.

You may be able to create “empty” stacks, frames, series on the main thread and just get the important bits from the web workers by posting…

0reactions
hurryhuang1007commented, Sep 16, 2018

@NicolasRannou Sorry to have kept you waiting so long. And I am finish it now. https://github.com/hurryhuang1007/ami-worker-loader

Read more comments on GitHub >

github_iconTop Results From Across the Web

Using Web Workers - Web APIs - MDN Web Docs
Web Workers are a simple means for web content to run scripts in background threads. The worker thread can perform tasks without interfering ......
Read more >
Is there some kind of load event for web-workers?
As per last comment, I'll wrote my suggestion as answer: You can make the worker emit a message when they're loaded, and you...
Read more >
How Web Workers Work in JavaScript – With a Practical JS ...
In this article, I will walk you through an example that will show you how web workers function in JavaScript with the help...
Read more >
Understanding and Using Web Workers - CODE Magazine
The first thing that's different is the way the Web Worker script is loaded. Before, it was by instantiating the Worker object: the...
Read more >
Optimized media loading using the Web Workers API
The Web Workers API helps to solve the decades-old issue of efficiently loading media into JavaScript-based web applications.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found