React Native: Chain Async Calls. for example AsyncStorage?

I'm trying to chain multiple calls to AsyncStorage.getItem () but can't get the calls to run in the correct order. I seem to be able to break out of the loop when the last item has been completed before the previous items. It looks like React uses a different syntax for promises than jQuery does.

In this example, I am trying to chain the calls to get vars v1, v2, v3. v3 triggers a UI update that requires vars v1 and v2. My code for two chain brews looks like this:

AsyncStorage.getItem("v1")
.then(
    (value) => {
        if (value !== null){
            varCollection.v1 =value
        }
    }
)
.then( () => {
    AsyncStorage.getItem("v3")
    .then((value) => {
        if (value !== null){
            varCollection.v3 = value;
        }else{
            varCollection.v3 = "default value";
        }
    })
    .done()
})
.done();

      

It seems to work, but it might just be luck that makes it work, when I add another link to the chain everything goes wrong.

AsyncStorage.getItem("v1")
.then(
    (value) => {
        if (value !== null){
            varCollection.v1 =value
        }
    }
)
.then( () => {
    AsyncStorage.getItem("v2")
    .then((value) => {
        if (value !== null){
            varCollection.v2 = value;
        }
    })
    .done()
})
.then( () => {
    AsyncStorage.getItem("v3")
    .then((value) => {
        if (value !== null){
            varCollection.v3 = value;
        }else{
            varCollection.v3 = "default value";
        }
    })
    .done()
})
.done();

      

This changes v3 and activates the state of the application, even if v2 has not been assigned yet.

Calling console.log () on each of the vars in props.varCollection from getInitialState () of the children shows that v1 is present but v2 is not, or vice versa. I also tried nesting my calls in order to create a chain, which I realized quickly got confused.

* Update * In addition to the suggestions from SLacks and Bergi, I've also tried the following:

AsyncStorage.getItem("v1")
.then((value) => {
    if (value !== null){
        v1 = value;
    }
})
.then( () =>{
    return( 
        AsyncStorage.getItem("v2")
        .then((value) => {
            if (value !== null){
                v2 = value;
            }
        })
    )
})
.then( () => {
    return(
        AsyncStorage.getItem("v3")
        .then((value) => {
            if (value !== null){
                v3 = value;
            }
        })
    )
})
.done();

      

and

AsyncStorage.getItem("v1")
.then((value) => {
    if (value !== null){
        v1 = value;
    }
})
.then( () =>
    ( 
        AsyncStorage.getItem("v2")
        .then((value) => {
            if (value !== null){
                v2 = value;
            }
        })
    )
)
.then( () => 
    (
        AsyncStorage.getItem("v3")
        .then((value) => {
            if (value !== null){
                v3 = value;
            }
        })
    )
)
.done();

      

but still stuck in the second call.

* / Update *

What's the correct way to wire up async calls in React Native?

+3


source to share


3 answers


I'm not sure why the suggested syntax from Bergi didn't work, but I found that there was a separation of call and assignment before and after the then statement strictly controlled the order, and that the return statement should only return the promise from the last call in each block. This may not be the best way to do it, but it seems to work well for sequential synchronous reads.

AsyncStorage.getItem("v1")
.then( (value) =>
      {
        this.setState({v1:value})
        return AsyncStorage.getItem("v2")
      }
)
.then( (value) =>
    {
        this.setState({v2: value})
        return AsyncStorage.getItem("v3")
    }
)
.then( (value) =>
    {
        this.setState({v3:value})
        return AsyncStorage.getItem("v4")
    }
)
.then( (value) =>
    {
        return this.setState({v4:value})
    }
).done();

      



You can see it in action at https://rnplay.org/plays/51t0cQ

+4


source


You need return

those promises from the callbacks then

. Just put a statement return

in front of each, or omit the blocking block of your arrow function.



Then you also only need one .done()

at the end.

+2


source


Update: react native es7 async media awaits now.
So now you can do something like this,

let x = await <Promisified/async functions>
let y = //use x 

      

and don't forget to wrap it in try, catch;)

+1


source







All Articles