【问题标题】:Return value wrapped around anonymous function in javascriptjavascript中匿名函数的返回值
【发布时间】:2025-12-08 21:25:01
【问题描述】:

有人可以向我解释checkX() 的范围有什么问题吗?我怀疑这是错误的,匿名函数以某种方式阻止了它,但我不确定如何绕过它。

storage = chrome.storage;

function checkX(){
    var x = false;

    storage.sync.get(function(data){
        if(data.x == true){
                x = true;
                console.log(x); // << x : true
        }
    });

            console.log(x); // << x : false
    return x;
}

console.log 结果顺序:

x : false
x : true

【问题讨论】:

  • Javascript 区分大小写:x != X
  • 编辑后,这似乎是典型的异步问题。
  • 我在我的问题中添加了一些关于 storage.sync 的信息

标签: javascript scope anonymous-function


【解决方案1】:

2 件事可能——也可能会——让你失望:

  1. JavaScript 区分大小写
  2. 你使用的get方法是异步,你的IIFE在传递的回调函数执行之前返回,所以它会在回调之前返回x的值无论如何都会改变它。

编辑:
get 方法只是一个 getter,很公平,但是 chrome.storage.sync.getchrome.storage.local.get 之间有一个主要区别,它使用 google 同步获取数据,这(几乎)与使用 @987654327 相同@object,具有事件的额外好处。至少,Google's docs 乍一看是这样告诉我的?

来自下面的 cmets:
这里的问题是 JS 如何以及何时调用回调函数。即使 OP 使用的 getter 正在获取 local 数据,IIFE 也必须先返回,然后 JS 作为单线程才能调用回调。这就是 IIFE 返回false 的原因。

【讨论】:

  • 我不小心把 X 大写了,这不是真正的问题。我还在我的问题中添加了一些关于 storage.sync 的信息
  • @AdonisK.: 嗯,添加的信息实际上证实了问题是 get 方法的异步字符,正如我在第二点中所说:调用了 IIFE,调用 get方法,并返回,当get 方法收到答案时,它会调用回调函数。到那时,IIFE 早就回来了……
  • 但是get函数只是一个getter函数,它不涉及HTTP GET方法。
  • @AdonisK.: 没关系,你调用一个函数,然后将回调作为参数传递给它。由于 JS 是单线程,回调将被移到队列的后面,在它被调用之前! IIFE 只是 HAS 先返回。 callback 基本上是说 Do this,当我给你回电时。现在,我要完成这个,首先数据来自哪里完全无关紧要。这就是为什么在回调中,被调用的上下文(this 引用)将指向全局对象,它在其他时间、其他地方被调用!
  • @AdonisK。我不是在谈论sync.get 我在谈论JS 如何处理回调。 get 方法是在 IIFE 的范围内调用的,所以它被立即调用。回调是尽快调用的函数调用,但是由于JS是单线程的,并且IIFE尚未返回,回调必须等待轮到它 .这其中的哪一部分不清楚? JS 不能调用在被调用的函数返回之前传递给另一个函数的回调。它是先记录true,然后再记录false,还是反过来?
【解决方案2】:

Javascript 区分大小写。你正在做的是创建一个全局变量x,即true,而局部变量X仍然是false

storage = chrome.storage;

function checkX(){
    var X = false;

    storage.sync.get(function(data){
        if(data.x == true){
            x = true;  <--- global variable
        }
    });

    return x;
}

另一个问题是,如果storage.sync.get 从“checkX”异步运行,这意味着首先您返回 x,只有稍后(在您返回它之后)才会执行您的函数。如果 storage.sync.get 是一个 ajax 调用,这肯定会发生。

【讨论】:

  • 我不小心把 X 大写了,这不是真正的问题。我还在我的问题中添加了一些关于 storage.sync 的信息