在函数内部修改变量后,为什么变量未更改? -异步代码参考

本文翻译自:Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference

Given the following examples, why is outerScopeVar undefined in all cases? 给定以下示例,为什么在所有情况下都未定义outerScopeVar

var outerScopeVar;

var img = document.createElement('img');
img.onload = function() {
    outerScopeVar = this.width;
};
img.src = 'lolcat.png';
alert(outerScopeVar);

var outerScopeVar;
setTimeout(function() {
    outerScopeVar = 'Hello Asynchronous World!';
}, 0);
alert(outerScopeVar);

// Example using some jQuery
var outerScopeVar;
$.post('loldog', function(response) {
    outerScopeVar = response;
});
alert(outerScopeVar);

// Node.js example
var outerScopeVar;
fs.readFile('./catdog.html', function(err, data) {
    outerScopeVar = data;
});
console.log(outerScopeVar);

// with promises
var outerScopeVar;
myPromise.then(function (response) {
    outerScopeVar = response;
});
console.log(outerScopeVar);

// geolocation API
var outerScopeVar;
navigator.geolocation.getCurrentPosition(function (pos) {
    outerScopeVar = pos;
});
console.log(outerScopeVar);

Why does it output undefined in all of these examples? 为什么在所有这些示例中都输出undefined I don't want workarounds, I want to know why this is happening. 我不想要解决方法,我想知道为什么会这样。


Note: This is a canonical question for JavaScript asynchronicity . 注意:这是JavaScript异步性的典型问题。 Feel free to improve this question and add more simplified examples which the community can identify with. 随时改进此问题,并添加更多简化的示例,社区可以识别。


#1楼

参考:https://stackoom.com/question/1bItC/在函数内部修改变量后-为什么变量未更改-异步代码参考


#2楼

One word answer: asynchronicity . 一句话回答: 异步性

Forewords 前言

This topic has been iterated at least a couple of thousands of times, here, in Stack Overflow. 在Stack Overflow中,该主题已至少迭代了数千次。 Hence, first off I'd like to point out some extremely useful resources: 因此,首先,我想指出一些非常有用的资源:


The answer to the question at hand 眼前问题的答案

Let's trace the common behavior first. 让我们首先跟踪常见行为。 In all examples, the outerScopeVar is modified inside of a function . 在所有示例中, outerScopeVarfunction内部进行修改。 That function is clearly not executed immediately, it is being assigned or passed as an argument. 该函数显然不会立即执行,而是被分配或作为参数传递。 That is what we call a callback . 这就是我们所说的回调

Now the question is, when is that callback called? 现在的问题是,何时调用该回调?

It depends on the case. 这要视情况而定。 Let's try to trace some common behavior again: 让我们尝试再次跟踪一些常见行为:

  • img.onload may be called sometime in the future , when (and if) the image has successfully loaded. img.onload可能在将来的某个时间(如果(如果))图像成功加载img.onload调用。
  • setTimeout may be called sometime in the future , after the delay has expired and the timeout hasn't been canceled by clearTimeout . setTimeout可能会在延迟到期后并且clearTimeout尚未取消超时之后的将来某个时间调用。 Note: even when using 0 as delay, all browsers have a minimum timeout delay cap (specified to be 4ms in the HTML5 spec). 注意:即使将0用作延迟,所有浏览器都具有最小超时延迟上限(在HTML5规范中指定为4ms)。
  • jQuery $.post 's callback may be called sometime in the future , when (and if) the Ajax request has been completed successfully. jQuery $.post的回调可能在将来的某个时间(当Ajax请求已成功完成时)被调用。
  • Node.js's fs.readFile may be called sometime in the future , when the file has been read successfully or thrown an error. 当文件已被成功读取或引发错误时, 将来可能会调用Node.js的fs.readFile

In all cases, we have a callback which may run sometime in the future . 在所有情况下,我们都有一个回调,它可能在将来的某个时间运行。 This "sometime in the future" is what we refer to as asynchronous flow . 这种“将来的某个时候”就是我们所说的异步流

Asynchronous execution is pushed out of the synchronous flow. 异步执行从同步流中推出。 That is, the asynchronous code will never execute while the synchronous code stack is executing. 也就是说,异步代码将永远不会在同步代码堆栈执行时执行。 This is the meaning of JavaScript being single-threaded. 这就是JavaScript是单线程的意思。

More specifically, when the JS engine is idle -- not executing a stack of (a)synchronous code -- it will poll for events that may have triggered asynchronous callbacks (eg expired timeout, received network response) and execute them one after another. 更具体地说,当JS引擎处于空闲状态时-不执行(a)同步代码的堆栈-它将轮询可能触发异步回调的事件(例如

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值