Roku Developer Program

Join our online forum to talk to Roku developers and fellow channel creators. Ask questions, share tips with the community, and find helpful resources.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
kidasov
Channel Surfer

Run task in for loop

Hello guys! I get stuck with the problem. I am trying to get data asynchronously from the server in for loop.

i = 0

    for each album in albums
        videosInAlbum = album.metadata.connections.videos.total
        
        if (videosInAlbum > 0)
            i += 1        
            newAlbum = CreateAlbum()
            newAlbum.setName(album.name)
        
            newAlbum.setUrl(album.link)
            newAlbum.setUri(album.uri)
            newAlbum.setDescription(album.description)
        
            if (album.pictures <> invalid)
                link = album.pictures.sizes[album.pictures.sizes.count() * 0.5].link
                
                newAlbum.setPosterURL(link)
                
                m.cacheImageTask.setField("fileName", "tmp:/file" + i.toStr() + ".jpg"
               m.cacheImageTask.setField("url", link)
                m.cacheImageTask.control = "RUN"
               m.cacheImageTask.observeField("response","onImageCached")
            end if
            newAlbum.setTotalVideos(videosInAlbum)
    
            m.user.addAlbum(newAlbum)
            m.addAlbumToHomeScene(newAlbum)
        end if
    end for

CacheImageTask.xml

<?xml version="1.0" encoding="UTF-8"?>
<component name="CacheImageTask" extends="Task" xsi:noNamespaceSchemaLocation="https://devtools.web.roku.com/schema/RokuSceneGraph.xsd">
<script type="text/brightscript" uri="pkg:/components/tasks/CacheImageTask/CacheImageTask.brs" />
<interface>
<field id="url" type="string" />
<field id="params" type="stringarray" />
<field id="builtInParams" type="stringarray" />
<field id="response" type="string" alwaysNotify="true" />
<field id="request" type="string" alwaysNotify="true" />
<field id="fileName" type="string" alwaysNotify="true" />
</interface>
</component>

CacheImageTask.brs
sub init()
    m.top.functionName = "executeTask"  
    m.counter = 0
    print("In cacher image task")
end sub

function executeTask()
    url = m.top.url
    print("Filename: "+ m.top.fileName)
    urlTransfer = CreateObject("roURLTransfer")
    urlTransfer.SetURL(url)
  urlTransfer.getToFile(m.top.fileName)
    m.top.response = url
    m.top.request = url
end function


The main problem is that I can not change fields of the task in for loop, because in the function executeTask()  m.top.fileName will always be equal to the last i-number of the loop. So how I can run one task multiple times in for loop with unique data for each iteration?
0 Kudos
1 REPLY 1
joetesta
Roku Guru

Re: Run task in for loop

if you're running them simultaneously I believe you need to use distinct tasks; create a new task with a distinct ID each time through.  If you're wanting to re-use the same task then you probably don't want run the task within the for-loop, or don't use a for-loop and come up with a way that each new task is triggered when the previous completes.  This is probably preferable from a "don't overload bandwidth and or roku processor with a bunch of simultaneous requests" standpoint.

The problem with the for loop now is that it modifies the task (repeatedly) before it completes, and the task has to call a function outside of the for loop upon completion.  So you could have a bunch of distinct tasks running in parallel, or re-use the same task but do so sequentially, after each run completes, then modify and call the next task.  keep a counter of completed tasks so when the last one completes it knows not to call any more.

m.tasksToLoad = albums.Count()
m.counter = 0


then in the callback

m.counter++
if m.counter < m.tasksToLoad then launchNextTask()
aspiring
0 Kudos