Serhii Kozachenko
Serhii Kozachenko

Reputation: 1401

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?

Upvotes: 6

Views: 3390

Answers (2)

Serhii Kozachenko
Serhii Kozachenko

Reputation: 1401

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).

Upvotes: 7

AlexeyKuznetsov
AlexeyKuznetsov

Reputation: 412

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.

Upvotes: 1

Related Questions