indexeddb:在请求过程中更改变量名如何导致错误?

mzaanser  于 2022-12-09  发布在  IndexedDB
关注(0)|答案(1)|浏览(174)

我正在学习indexeddb,在比较下面的两个函数时感到困惑。它们是相同的,除了我将代码#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

代码#1错误在console.log(request.result)行。我尝试使用chrome devtools调试器,发现调试器从来没有使它到var request = store.put(entry),这使我更加困惑。
代码#1错误,因为请求未定义。我在概念上不明白重新定义request以后会改变什么。任何帮助都很感激,谢谢。

46scxncf

46scxncf1#

有趣的是,我认为这与javascript中所谓的“提升”有关。
基本上,提升意味着代码中的变量声明被“带到代码的顶部”。在声明AND初始化变量的情况下,就像你对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)。
当您将名称变更为request 2时,它也会以类似方式提升,但不会覆写外部的request,因此request.result不是undefined。
这有道理吗?

相关问题