异步执行回调时为何仍能访问loadItem的sName参数?
为什么异步回调里还能访问loadItem的sName参数?
这其实是JavaScript里**闭包(Closure)**在起作用,咱们一步步拆解来看:
首先看你写的loadItem函数:
function loadItem(sName, callback){ var get = {}; get[sName] = {}; //blank obj by default. chrome.storage.local.get(get, function(data) { data[sName] && callback(data[sName]); }); };
当你调用loadItem的时候,JavaScript会为这个函数调用创建一个独立的作用域,里面包含了sName、callback这两个参数,还有get变量。
虽然loadItem函数本身会很快执行完毕,但你传给chrome.storage.local.get的那个匿名回调函数,会保留对这个外部作用域的引用——这就是闭包的核心:内部函数可以访问并保留外部函数作用域中的变量,哪怕外部函数已经执行完成。
等chrome.storage.local.get的异步操作完成、触发回调时,这个回调函数依然能“找到”当初loadItem执行时的sName变量,因为闭包把这个作用域给“保存”下来了。
举个更简单的例子帮你理解:
function sayHiLater(name) { // 异步延迟1秒执行回调 setTimeout(function() { console.log(`Hi, ${name}!`); }, 1000); } sayHiLater("Bob");
哪怕sayHiLater执行完立刻退出了,1秒后回调依然能打印出Hi, Bob!,原理和你的代码完全一样——闭包让内部的异步回调记住了外部作用域的name变量。
你之前的误解“异步回调不应识别该变量”其实是不对的,闭包就是JavaScript专门用来处理这种场景的特性,不管回调是同步还是异步,只要它是在某个外部作用域里定义的,就能通过闭包访问那个作用域里的变量。
内容的提问来源于stack exchange,提问作者tripRev
相关产品推荐
相关产品推荐

