【问题标题】:External variable access when chaining Promises [duplicate]链接 Promises 时的外部变量访问 [重复]
【发布时间】:2018-05-04 20:11:25
【问题描述】:

我在 JS 中有一个大问题。

我有一个函数,我可以在其中创建一个承诺链。一个承诺被“添加”到 for 循环中的最后一个承诺。在这个循环里面有一些变量。每个then的每个函数都需要访问这些变量,即它们的值对应正确的进行迭代。

我认为,问题在于,由于 promise 是在函数结束时执行的,所以每个 promise 都会读取这些变量的相同值(它们具有最后一次迭代的值)。

我不希望这种情况发生。我该如何解决?

我已经编写了一个模仿我的问题的代码:

function test() {
var p = Promise.resolve();
for (var i = 0; i < 10; i++) {
	var j = i * 10;
	p = p.then(function() {
		alert(j);
	});
}
  
p.then(function() {
	alert('finished');
})

}

test();

如您所见,每次内部函数触发时,它总是读取 j 的值 90,而不是读取所有正确的值。

感谢您的帮助

【问题讨论】:

  • 你的第一个 promisep 只会在整个 for 循环完成后执行,因为 promise 是异步的,而 for 循环是同步的。在 for 循环完成时 j 已经被分配到 90。Alert(j) 只是显示一条只有一个内容的消息..j。所以你得到的只有 90。

标签: promise chaining


【解决方案1】:

var 更改为let,然后循环的每次调用都会有自己的一组变量。

function test() {
    let p = Promise.resolve();
    for (let i = 0; i < 10; i++) {
    	let j = i * 10;
    	p = p.then(function() {
    		console.log(j);
    	});
    }
      
    p.then(function() {
    	console.log('finished');
    })
}

test();

let 是块作用域,因此每个块(在这种情况下是 for 循环的每次迭代)都有自己的 ij 变量版本。因此,当您执行 alert(j) 时,它将使用正确的变量。

仅供参考,我将alert(j) 更改为console.log(j),因为使用alert() 可能会干扰异步计时(因为它会阻止JS 执行),而console.log() 只是报告并让代码继续运行,以便您更好地了解console.log() 的实际运行情况。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-22
    • 2015-03-05
    • 2022-12-02
    • 2023-04-08
    相关资源
    最近更新 更多