约定闭包是否会以异步方式影响价值?

时间:2019-08-20 06:21:59

标签: javascript asynchronous closures es6-promise

在第二个then方法中,有一个封闭的值(字符串),我正在运行setTimeout以在1秒后更改它。 另外,我还返回了新的Promise,以便在2秒钟后使用setTimeout解析为我使用先前的setTimeout更改的值。 但是在下一次解决之后,方法将注销不受先前setTimeout影响的值。 我不应该从上一个方法的日志中获取“ foobarbaz”。

预先感谢...

var p1 = new Promise((resolve, reject) => {
  resolve('foo');
});
p1.then(function(string) {
  return new Promise(res => {
    setTimeout(() => {
      string += 'bar';
      res(string);
    }, 2000);
  });
})
.then(function(string) {
  setTimeout(function() {
    string += 'baz';
    console.log(string);
  }, 1000);
  return new Promise(resolve => setTimeout(resolve, 2000, string));
})
.then(function(string) {
  console.log(string);
});

1 个答案:

答案 0 :(得分:0)

问题是:

return new Promise(resolve => setTimeout(resolve, 2000, string));

这会导致setTimeout在行运行的那一刻在string变量中得到当前 的参数-尽管string被重新分配了上方的setTimeout表示setTimeout尚未运行,因此string仍为foobar

类似地:

let a = 'foo';
setTimeout(console.log, 200, a);
a = 'bar';

导致foo被记录,而不是bar

如果传递的函数在调用时引用了string绑定的内容,则调用该函数时,结果将符合预期:

return new Promise(resolve => setTimeout(() => {
  resolve(string);
}, 2000));

var p1 = new Promise((resolve, reject) => {
  resolve('foo');
});
p1.then(function(string) {
  return new Promise(res => {
    setTimeout(() => {
      string += 'bar';
      res(string);
    }, 2000);
  });
})
.then(function(string) {
  setTimeout(function() {
    string += 'baz';
    console.log(string);
  }, 1000);
  return new Promise(resolve => setTimeout(() => {
    resolve(string);
  }, 2000));
})
.then(function(string) {
  console.log(string);
});