Roku Developer Program

Developers and content creators—a complete solution for growing an audience directly.
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
kidasov
Level 7

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
joetesta
Level 10

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