Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

rxjs use async/await in map Rx.Observable.range(1, 5).map

I want get a list from rxjs using async/await. What should I do?

function getData(num){
    return new Promise((resolve, reject)=>{
        resolve(num + 1)
    })
}

async function create(){
    var list = await Rx.Observable.range(1, 5).map(async (num)=>{
        const data = await getData(num)
        return  data
    }).toArray().toPromise()

    return list
}


Rx.Observable.fromPromise(create()).subscribe(list=>{
    console.log(list)
}, err=>{
    console.log(err)
})

I get

[ Promise { 2 },
  Promise { 3 },
  Promise { 4 },
  Promise { 5 },
  Promise { 6 } ]

I want get data like this

[2,3,4,5,6]
like image 933
Moon Avatar asked Jun 03 '16 10:06

Moon


People also ask

Can I use async await with Observable?

You can use Observables with Promises and with async/await to benefit from the strengths of each of those tools.

Can I use async await inside map?

If you use the async await function and console out the output, then you will find the arrays of promises that are still needed to be resolved. The map doesn't resolve the promises on its own but left the stuff for the developer to resolve. So, that means you can't use async-await in the map.

Does map work with async?

map() algorithm applies an async callback to each element of an array, creating promises as it does. However, the returned result by . map() is no promise, but an array of promises.

Can you use async await with arrow function?

async is used to make a function asynchronous. It unlocks the use of await inside these functions. Using await in any other case is a syntax error. Notice the use of async keyword at the beginning of the function declaration. In the case of arrow function, async is put after the = sign and before the parentheses.


1 Answers

It's a slightly old question. You might have got the answer already, but I thought it's a nice challenge, which turned out to be a surprisingly simple one too!

Just switch from map() to concatMap().

And you won't even need the async / await bit inside the mapping function. Although keeping or removing it doesn't seem to change anything for me.

So, the relevant bit can be simplified to:

async function create() {
  var list = await Rx.Observable.range(1, 5)
    .concatMap(num => getData(num))
    .toArray().toPromise();

  return list;
}

And again, you can keep it exactly as you had it in the question, and just change map to concatMap. I just wanted to see how far this can go

Here's a working example

Check the console at the bottom of the page for the results.

like image 91
Meligy Avatar answered Sep 20 '22 15:09

Meligy