Функции с замыканием по одному аргументу, а по другому возврат из обещания? - PullRequest
0 голосов
/ 12 февраля 2020

Я борюсь с блоком кода, включающим замыкания в наборе обещаний. Этот пример иллюстрирует проблему. Проблема заключается в том, что последний из этих трех примеров обещаний закрывается на q и использует результат обещания. Первые две работы, и это, кажется, потому, что обработчики успеха обещаний являются просто функцией замыкания без какого-либо другого аргумента, то есть результат обещания явно не передается в качестве аргумента. Функция успеха третьего обещания пытается передать свойство результирующего объекта, но это приводит к тому, что в 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);
}

Ответы [ 2 ]

2 голосов
/ 13 февраля 2020

Опуская весь этот ненужный хаос IIFE, вы, по сути, имеете

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

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

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

Разница в том, что в третьем примере переменная q вычисляется внутри функции o => … arrow, которая вызывается асинхронно после назначения q = 7. Напротив, другие два сразу оценивают q, поэтому для него требуются значения 1 и 5 соответственно.

Чтобы это исправить, напишите

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

См. Также закрытие не работает .

1 голос
/ 13 февраля 2020

Функция, переданная методу then в примере promise_test_obj, будет выполнена через 100 мс, когда значение q во внешней области установлено на 7.

  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)

вызывается асинхронно, тогда как в двух других примерах он вызывается синхронно.

...