Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ES6 yield multiple generators

In ES6 yield and generator function allow to await once function will execute. But I want to await multiple generators. Here the code:

files.forEach(function* (file) {
    const uploadedFile = yield call([service, service.upload], file, config)
}

call is redux-saga effect

To express the Saga logic we yield plain JavaScript Objects from the Generator. We call those Objects Effects

I want to fire all uploads in one time, without waiting before previous finished and wait once all files got uploaded, is it possible with yield?

like image 730
Sergiy Kozachenko Avatar asked Apr 04 '17 11:04

Sergiy Kozachenko


2 Answers

What I was looking for was actually this:

// correct, effects will get executed in parallel
const [users, repos]  = yield [
  call(fetch, '/users'),
  call(fetch, '/repos')
]

call here is just returning promise

When we yield an array of effects, the generator is blocked until all the effects are resolved or as soon as one is rejected (just like how Promise.all behaves).

like image 130
Sergiy Kozachenko Avatar answered Oct 30 '22 18:10

Sergiy Kozachenko


You can use Promise.all() instead

EXAMPLE:

If you want to fire all uploads and regain control of the code after they all finished you can use async/await interface:

function uploadALL(files){
  const uploadedFilesPromises = files.map( file => {
    return call([service, service.upload], file 
  })        
  }
  return Promise.all(uploadedFilesPromises);
} 

// samples of using this function:
uploadALL(files).then((uploadedFiles)=> { ....  })
// or in async function you can use await:
const uploadedFiles = await uploadAll(files)

Your "call" method should return a Promise object, otherwise you have to wrap it into Promise.

like image 20
AlexeyKuznetsov Avatar answered Oct 30 '22 18:10

AlexeyKuznetsov