React Native:链异步调用。例如AsyncStorage?

时间:2015-05-29 15:02:30

标签: javascript promise react-native

我试图将几个调用链接到AsyncStorage.getItem(),但似乎无法以正确的顺序触发调用。我似乎设法在早期项目之前完成最后一项完成后退出循环。似乎React使用与promise相同的语法而不是jQuery的工作方式。

在这个例子中,我试图链接调用以获取vars v1,v2,v3。 v3触发刷新需要vars v1和v2的UI。我的两个链式变量的代码如下:

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();

这似乎有效,但它可能只是运气,导致它工作,因为当我添加链的另一个链接,出了问题。

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();

这导致v3更改并触发应用程序的状态更改,即使v2可能尚未分配。

从子元素的getInitialState()调用props.varCollection中的每个变量上的console.log()显示v1存在但v2不是,反之亦然。我也试过嵌套我的调用来创建链条,我意识到它很快就会变得混乱。

*更新* 除了SLack和Bergi的建议之外,我还尝试了以下内容:

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();

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();

但在第二次通话时仍然卡住了。

* /更新*

在React Native中链接异步调用的正确方法是什么?

3 个答案:

答案 0 :(得分:6)

我不确定为什么Bergi的建议语法不起作用但是我发现在then语句之前和之后分离调用和赋值允许严格控制排序,并且return语句应该只返回来自每个块中的最后一个调用。这可能不是最好的方法,但它似乎对顺序同步读取非常有效。

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();

您可以在https://rnplay.org/plays/51t0cQ

看到它的实际效果

答案 1 :(得分:2)

您需要return来自then回调的承诺。{p}只需在每个语句前添加return语句,或省略箭头函数的块括号。

然后你最后也只需要一个.done()

答案 2 :(得分:1)

更新:React native支持es7 async等待 所以你现在可以这样做,

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

并且不要忘记在try,catch中抓包装;)