【问题标题】:React Native: Chain Async Calls. e.g to AsyncStorage?React Native:链式异步调用。例如到 AsyncStorage?
【发布时间】:2015-08-12 12:25:10
【问题描述】:

我正在尝试将多个调用链接到 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 中的每个 var 调用 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 中链式异步调用的正确方法是什么?

【问题讨论】:

  • 你需要将 Promise 返回到链中。
  • 我该怎么做?

标签: javascript promise react-native


【解决方案1】:

您需要 return 来自 then 回调的那些承诺。只需在每个前面加上 return 语句,或省略箭头函数的大括号即可。

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

【讨论】:

  • 谢谢,但我在执行此操作时遇到了麻烦。我已经尝试了这两种建议,但仍然无法让它们比第二项更进一步。我将编辑问题以包含我尝试过的变体。
  • 我现在已经编辑了问题以包含我认为您建议的代码。有什么想法吗?
  • 嗯,那些看起来不错。您可能需要仔细检查它们是否编译为 ES5 代码中的 return 语句。除此之外,您使用的承诺实现可能是虚假的,但我不敢相信。
  • 好的,我解决了。在您所说的地方添加返回,对我不起作用,但在下一个排队调用之前添加它效果很好,然后在下一个代码块中分配值。谢谢您的输入。
【解决方案2】:

我不确定为什么来自 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看到它的实际应用

【讨论】:

    【解决方案3】:

    更新:React Native 现在支持 es7 异步等待。
    所以你现在可以做这样的事情,

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

    别忘了把 then 换成 try,catch ;)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-02
      • 1970-01-01
      • 1970-01-01
      • 2019-03-21
      • 2019-11-03
      • 1970-01-01
      • 2019-01-20
      • 1970-01-01
      相关资源
      最近更新 更多