как передать по значению в JavaScript обещание - PullRequest
0 голосов
/ 07 ноября 2018

Я не понимаю поведение этой программы javascript. Мое намерение состояло в том, чтобы последовательно извлечь три пронумерованных ресурса, но кажется, что «i» было захвачено в замыкании, и используется только его окончательное значение.

function fetch(x) {
    console.log('fetching resource ' + x);
}

var prom = Promise.resolve();
for(var i=1; i<=3; i++) {
    prom = prom.then(() => { fetch(i);} );
}

//prints
//fetching resource 4
//fetching resource 4
//fetching resource 4

Я не знаю достаточно о js, чтобы решить эту проблему - как я могу изменить эту программу для получения 1, 2 и 3? Нужно ли где-нибудь использовать resol ()?

ОБНОВЛЕНИЕ: было отмечено, что этот вопрос дублирует закрытие JavaScript внутри циклов - простой практический пример , что технически верно, но, тем не менее, я думаю, что этот вопрос имеет свои достоинства из-за его нового применения в мир обещаний. Технически, вышеупомянутый вопрос действительно правильно отвечает на поставленный здесь вопрос, потому что элемент Обещания в этом вопросе оказывается красной сельдью, не имеющей отношения к ответу. Но признание Обещания неуместным - это понимание, полученное при чтении этого вопроса, а не вышеупомянутого дубликата.

Ответы [ 5 ]

0 голосов
/ 07 ноября 2018

Проблема здесь не имеет ничего общего с Обещаниями и все, что связано с замыканиями. Ваш код:

for(var i=1; i<=3; i++) {
    prom = prom.then(() => { fetch(i);} );
}

означает «когда обещание разрешается, вызовите эту анонимную функцию, которая вызывает fetch() со значением current i». Текущее значение. Поскольку в этот момент вы уже вышли из цикла for (поскольку анонимная функция гарантированно не будет вызываться до тех пор, пока вы не вернетесь из этого кода), i равно 4.

Рики Мо предложил практичный способ сделать то, что вы, очевидно, хотите сделать.

0 голосов
/ 07 ноября 2018

Я предлагаю вам поместить обещание в цикл for, например:

function fetch(x) {
    console.log('fetching resource ' + x);
}


for(var i=1; i<=3; i++) {
    var prom = Promise.resolve(i);
    prom.then(fetch);
}

Или, если вы хотите определить обещание вне цикла, вы можете создать временный массив для использования Promise.all

function fetch(x) {
    console.log('fetching resource ' + x);
}

var arr = [];

for(var i=1; i<=3; i++) {
    arr.push(i);
}

Promise.all(arr).then(values =>
{
  values.forEach(fetch);
});
0 голосов
/ 07 ноября 2018

Изменить var на let

function fetch(x) {
    console.log('fetching resource ' + x);
}

var prom = Promise.resolve();
for(let i=1; i<=3; i++) {
    prom = prom.then(() => { fetch(i);} );
}

Или создайте IIFE для того же

function fetch(x) {
    console.log('fetching resource ' + x);
}

var prom = Promise.resolve();
for(var i=1; i<=3; i++) {
    prom = (function(i){ return prom.then(() => { fetch(i);} );})(i);
}
0 голосов
/ 07 ноября 2018

Заверните каждый контент для закрытия значения i;

function fetch(x) {
    console.log('fetching resource ' + x);
}

for(var i=1; i<=3; i++) {
     (function(index){Promise.resolve().then(() => { fetch(index);} )})(i);
}
0 голосов
/ 07 ноября 2018

Создайте const для хранения нужного значения.

function fetch(x) {
    console.log('fetching resource ' + x);
}

var prom = Promise.resolve();
for(var i=1; i<=3; i++) {
    const j = i;
    prom = prom.then(() => { fetch(j);} );
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...