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

React Native: Chain Async Calls. e.g to AsyncStorage?

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

在这个例子中,我尝试链接调用以获取变量 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();

这似乎有效,但可能只是运气使它正常工作,因为当我向链中添加另一个 link 时,出现了问题。

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 不存在,反之亦然。我还尝试嵌套我的调用以创建我意识到很快就会变得混乱的链。

* 更新 * 根据 SLacks 和 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 中链接异步调用的正确方法是什么?

您需要 return 来自 then 回调的承诺。只需在每个语句前面放置一个 return 语句,或者省略箭头函数的大括号。

那你最后也只需要一张.done()

我不确定为什么 Bergi 建议的语法不起作用,但我发现将 then 语句前后的调用和赋值分开允许严格控制顺序,并且 return 语句应该只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

看到它的实际效果

更新:React native 现在支持 es7 async await。
所以你现在可以做这样的事情了,

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

别忘了在 try,catch 中包装 then ;)