【问题标题】:Asynchronous behavior when calling a function from a react component从 React 组件调用函数时的异步行为
【发布时间】:2021-01-29 01:38:58
【问题描述】:

在功能性反应组件中,我声明了一个名为 IsCached 的状态变量(带有 useState)。 In 包含以下可点击图片。

    <img src={imgSource} alt="button images"
        onClick={function()
        {
         var return_value = CachePDF(props.docLink)
         console.log(return_value)
         if (return_value === true){
             SetIsCached(1)    
         }
         else{
             SetIsCached(0)
         }

        }
    }/> 

我的目标是,此按钮将调用函数 CachePDF,然后根据该函数是否成功将状态变量设置为 1 或 0。这是我的 CachePDF 函数:

export function CachePDF(url) {
    caches.open('favorites').then(function(cache) {
      var updateCache = cache.add(url);
      updateCache.then(function() {
        console.log("article was cached in favorites")
        caches.open("documents").then(function(cache){
            cache.delete(url).then(console.log("article removed from documents cache"))
        })
        return true
        
      }).catch(function (error) {
        console.log("article was not cached in favorites")
        return false
      })
    })
  }

现在我遇到的问题是 console.log(return_value) 的输出未定义,我认为这是由于异步行为而发生的。起初我以为我可以在 CachePDF 中返回一个承诺,以确保在 CachePDF 函数完成之前不会调用更改变量 IsCached 的代码。但据我了解,我需要在 CachePDF 函数中为返回的承诺定义 .then 方法,因此 .then 方法无法访问我的功能组件中的状态变量。所以我有点卡住了

【问题讨论】:

  • 您的 cachePDF 函数不返回任何内容。请记住,您在代码中看到的那些return 是用于function (cache) ... 函数,而不是CachePDF 函数

标签: javascript reactjs


【解决方案1】:

你可以像这样使用 async/await:

    <img src={imgSource} alt="button images"
        onClick={async function()
        {
         var return_value = await CachePDF(props.docLink)
         console.log(return_value)
         if (return_value === true){
             SetIsCached(1)    
         }
         else{
             SetIsCached(0)
         }

        }
    }/> 

你错过了函数 CachePDF 第一行的返回, updateCache.then 之前的另一个返回:

export function CachePDF(url) {
    return caches.open('favorites').then(function(cache) {
      var updateCache = cache.add(url);
      return updateCache.then(function() {
        console.log("article was cached in favorites")
        caches.open("documents").then(function(cache){
            cache.delete(url).then(console.log("article removed from documents cache"))
        })
        return true
        
      }).catch(function (error) {
        console.log("article was not cached in favorites")
        return false
      })
    })
  }

【讨论】:

  • CachePDF 函数仍然没有返回任何内容
  • 我添加了一个新的更改来返回...... ````CachePDF(url) { return```
  • @Dorian Winters 您是否能够检查正确答案,以便其他人可以从您的问题中学习?
  • 我已经测试了提供的两种解决方案,并且仍然收到它们的“未定义”行为。感谢您的回复,我认为我在解决问题方面走在了正确的轨道上,一旦我得到它的工作,我会回来提供任何更新
  • @DorianWinters 我已经意识到您在另一个缺少退货时遇到了另一个错误。
【解决方案2】:

CachePDF 目前不返回任何内容。从中返回承诺链很有用:

  • 结果可以使用
  • 控制执行顺序
export function CachePDF(url) {
    return caches.open('favorites').then(function(cache) {
      var updateCache = cache.add(url);
      updateCache.then(function() {
        console.log("article was cached in favorites")
        caches.open("documents").then(function(cache){
            cache.delete(url).then(console.log("article removed from documents cache"))
        })
        return true
        
      }).catch(function (error) {
        console.log("article was not cached in favorites")
        return false
      })
    })
  }

当 CachePDF 返回一个 Promise 时,我们可以向它添加处理程序:

    <img src={imgSource} alt="button images"
        onClick={function()
        {
         CachePDF(props.docLink).then(function (return_value) {
             console.log(return_value)
             if (return_value === true){
                 SetIsCached(1)    
             }
             else{
                 SetIsCached(0)
             }
         })
        }
    }/> 

附言

如果您转译代码或不需要广泛的浏览器支持,也可以使用 Async/await。它会更容易阅读并且非常接近您的原始代码(但在这种情况下也需要从 CachePDF 返回承诺):

    <img src={imgSource} alt="button images"
        onClick={async function()
        {
         var return_value = await CachePDF(props.docLink)
         console.log(return_value)
         if (return_value === true){
             SetIsCached(1)    
         }
         else{
             SetIsCached(0)
         }

        }
    }/> 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-25
    • 2019-01-13
    • 2020-04-20
    • 1970-01-01
    • 2017-08-13
    • 2017-07-20
    • 2022-12-12
    • 1970-01-01
    相关资源
    最近更新 更多