【问题标题】:Functions with closure on one argument and the other a return from a promise?一个参数有闭包,另一个参数是从承诺返回的函数?
【发布时间】:2020-02-12 20:58:11
【问题描述】:

我正在努力处理涉及一组承诺中的闭包的代码块。这个例子说明了这个问题。问题是让这三个 Promise 示例中的最后一个在 q 上关闭并使用 Promise 的结果。前两个有效,似乎是因为 Promise 的成功处理程序只是没有任何其他参数的闭包函数,这意味着 Promise 的结果没有作为参数显式传递。第三个 promise 的成功函数尝试传递结果对象的属性,但这导致q 上没有闭包。目标是让q 是 5 而不是 7。我很抱歉,因为我确信我使用了所有错误的编码术语。

你能解释一下我错过了什么吗?谢谢。

let q = 1;
let f = (function (x) {
  return function (r) {
    result(x, r);
  }
})(q);

q = 5;

promise_test().then((r) => {
  f(r);
}, () => { });

promise_test().then((function (x) {
  return function (r) {
    result(x, r);
  }
})(q), () => { });

promise_test_obj().then((o) => (function (x) {
  return function (r) {
    result(x, r);
  }
})(q)(o.m), () => { });

q = 7;

function promise_test() {
  return new Promise((resolve, reject) => {
    setTimeout(function () {
      resolve('promise test resolved');
    }, 100);
  });
}

function promise_test_obj() {
  return new Promise((resolve, reject) => {
    setTimeout(function () {
      resolve({ 'm': 'promise test_obj resolved' });
    }, 100);
  });
}

function result(a, r) {
  console.log('q : ' + a + ', r : ' + r);
}

【问题讨论】:

  • 哇,你真的应该清理你的代码格式。我希望这只是在此处发布时的一个问题,而不是您的实际来源。
  • @Gary 使用一些比单个字母更好的变量名对阅读您的代码更有帮助。照原样,它非常难以解析。
  • @Gary 没关系,以后只需粘贴您拥有的内容,然后单击tidy 按钮。在@Geuis 帮助进行格式化时,我将尝试破译这里发生的事情,但请也接受他对变量和函数名称的建议。
  • 对不起,我试过了,但我不明白这应该做什么,而且遵循逻辑至少很难说。如果您可以使用更清晰的变量和函数名称更新您的 sn-p,我可以再破解一次。如果您进行这些更新并希望我再看一下,请@我。
  • 我认为 success 函数直到 promise 解决后才会处理,因此 promise 中设置的闭包直到 q 的值改变后才会发生。在前两个 Promise 中,闭包是在 Promise 解决之前设置的。

标签: javascript promise closures


【解决方案1】:

省略所有不必要的 IIFE 混乱,你基本上有

q = 1,
f = (…)(q);

q = 5;
….then((…)(q));

….then(o => (…)(q)(o.m));
q = 7;

不同之处在于,在第三个示例中,q 变量在 o => … 箭头函数内部计算,该函数在 q = 7 赋值后异步调用。相比之下,其他两个立即评估q,因此它分别采用15 的值。

要解决这个问题,请写

f = (function(x) {
  return o => result(x, o.m)
}(q); // here q is still 5
promise_test_obj().then(f);

另见closure not working

【讨论】:

  • 您是一位真正的绅士,您深入研究并帮助了 Gary,我向您致敬并为您投票。
【解决方案2】:

promise_test_obj 示例中传递给then 方法的函数将在外部作用域中q 的值设置为7 时在100ms 后执行。

  o =>
    (function(x) {
      return function(r) {
        result(x, r);
      };
    })(q)(o.m),

因此,在使用参数{ m: "promise test_obj resolved" } 调用此函数时,q 的值为 7。上面示例中的以下代码:

(function(x) {
      return function(r) {
        result(x, r);
      };
    })(q)

被异步调用,而在其他 2 个示例中它被同步调用。

【讨论】:

  • 谢谢。我很欣赏它。我在您发布之前接受了答案,两者大致相同。再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多