【问题标题】:indexeddb: How does changing the variable names during a request cause one to error?indexeddb:在请求期间更改变量名称如何导致错误?
【发布时间】:2021-01-11 23:39:35
【问题描述】:

我正在学习 indexeddb,在比较下面的 2 个函数时我感到困惑。它们是相同的,只是我将代码#2 的最后一个 request 变量名称更改为变量 request2 名称。这会导致它们产生不同的结果。

代码#1

function updateEntry(){
    var tx = db.transaction('practiceStore', 'readwrite');
    var store = tx.objectStore('practiceStore');
    var request = store.get(3);
    request.onsuccess = event => {
        console.log(request.result)
        let entry = request.result;
        
        entry.title = 'mdn way'
        var request = store.put(entry)
        request.onsuccess = event => {
            console.log('putting')
        }
    }
    tx.oncomplete = event => {
        console.log('tx complete')
    }
}

输出:

errors

对比

代码#2

function updateEntry(){
    var tx = db.transaction('practiceStore', 'readwrite');
    var store = tx.objectStore('practiceStore');
    var request = store.get(3);
    request.onsuccess = event => {
        console.log(request.result)
        let entry = request.result;
        
        entry.title = 'mdn way'
        var request2 = store.put(entry)
        request2.onsuccess = event => {
            console.log('putting')
        }
    }
    tx.oncomplete = event => {
        console.log('tx complete')
    }
}

输出

//does expected behavior

console.log(request.result) 行中的代码#1 错误。我尝试使用 chrome devtools 调试器,发现调试器永远不会到达 var request = store.put(entry),这让我更加困惑。

代码#1 错误,因为请求未定义。从概念上讲,我不明白以后重新定义request 会如何改变任何事情。任何帮助表示赞赏,谢谢。

【问题讨论】:

  • 阅读varletconst
  • 你在开玩笑,我现在意识到没有第二次var request 是不必要的。我刚刚为request 删除了第二个var,它起作用了。但是,我仍然不明白第二个var request 会如何影响它之前发生的代码,尤其是当调试器甚至没有到达它时。我目前的理解是 var 功能范围。 let 是块作用域,const 除非它是一个对象,否则你不能更改它。编辑:@sheun 有帮助,这是有道理的。

标签: javascript indexeddb


【解决方案1】:

有趣的是,我认为这与 javascript 中称为“提升”的东西有关。

基本上,提升意味着代码中的变量声明被“带到代码的顶部”。在声明和初始化变量的情况下,就像您对 var request = store.put(entry) 所做的那样,声明 (var request;) 被提升到顶部,而不是初始化(实际上是分配 store.put 的结果)。

因此,当运行您的代码#1 时,实际上看起来像这样:

request.onsuccess = event => {
        var request; //this is the "hoisting" I am referring to
        console.log(request.result) //this is currently undefined now!
        let entry = request.result;
        
        entry.title = 'mdn way'
        request = store.put(entry) //this is the assignment
        request.onsuccess = event => {
            console.log('putting')
        }
    }

这有点令人困惑,但在这里 (https://www.w3schools.com/js/js_hoisting.asp) 解释得很好,尤其是关于提升声明而不是初始化的部分(参见链接中的示例 2)。

当您将名称更改为 request2 时,它同样会被提升,但不会覆盖外部请求,因此 request.result 不是未定义的。

这有意义吗?

【讨论】:

    猜你喜欢
    • 2014-08-03
    • 2012-10-02
    • 1970-01-01
    • 2012-01-10
    • 1970-01-01
    • 2020-08-13
    • 2017-02-11
    • 2013-06-15
    • 1970-01-01
    相关资源
    最近更新 更多