Как протолкнуть разрешение в массив с циклом? - PullRequest
0 голосов
/ 19 июня 2019

Когда я запускаю следующий код, возникает проблема с моим кодом.

Ожидаемый результат:

['test0,'test1','test2']

Фактический результат:

['test3','test3','test3']

Код:

var overall = [];

for(var a=0;a<3;a++){
    var test_promise = new Promise(function(resolve,reject){
        setTimeout(()=>{
            console.log("looping: " + a);
            resolve('test' + a);
        },3000);
    });

    overall.push(test_promise);
}

Promise.all(overall).then(function(value){
    console.log(value);
});

Ответы [ 4 ]

4 голосов
/ 19 июня 2019

Чтобы исправить это, вы должны изменить var на let in for loop (проблема замыкания)

for(let a=0;a<3;a++)

Результат выше, потому что var определяет переменнуюглобально или локально для всей функции независимо от области видимости блока.

let позволяет объявлять переменные, ограниченные по области действия блоком, оператором или выражением, в котором она используется.Это не похоже на ключевое слово var, которое определяет переменную глобально или локально для всей функции независимо от области видимости блока.

, например,

for(var i = 1; i <= 5; i++) {
   setTimeout(function() {
       console.log('Value of i : ' + i); 
   },100);
} 

Желаемый вывод кода выше

Value of i : 1
Value of i : 2
Value of i : 3
Value of i : 4
Value of i : 5

Но вывод фактического равен

Value of i : 6
Value of i : 6
Value of i : 6
Value of i : 6
Value of i : 6

Вышеуказанный результат объясняется тем, что var определяет переменную глобально или локальнодля всей функции независимо от объема блока.

for(let i = 1; i <= 5; i++) {

   setTimeout(function(){
       console.log('Value of i : ' + i);
   },100);
}
Output:
Value of i : 1
Value of i : 2
Value of i : 3
Value of i : 4
Value of i : 5

в вашем случае ваш код будет:

for(let a=0;a<3;a++){
    var test_promise = new Promise(function(resolve,reject){
        setTimeout(()=>{
            console.log("looping: " + a);
            resolve('test' + a);
        },3000);
    });

    overall.push(test_promise);
}
0 голосов
/ 19 июня 2019

Вместо использования var in для цикла используйте let. Вы можете получить лучшее представление о var и let отсюда Разница между var и let?

var overall = [];

for(let a=0;a<3;a++){
    var test_promise = new Promise(function(resolve,reject){
        setTimeout(()=>{
            console.log("looping: " + a);
            resolve('test' + a);
        },3000);
    });

    overall.push(test_promise);
}

Promise.all(overall).then(function(value){
    console.log(value);
});
0 голосов
/ 19 июня 2019

быстрый ответ: используйте let a = 0 вместо var a = 0

более длинный ответ: var поднимается глобально, а let и const поднимаются в зависимости от текущей области видимости. Поэтому, когда вы отправляете массив после тайм-аута, он принимает текущее значение a, то есть последнюю итерацию цикла for. При использовании const или let в закрытии будет использовано значение a a твое обещание.

0 голосов
/ 19 июня 2019

Вам нужно использовать let и передать значение в обещание следующим образом:

 

var overall = [];

for(let a=0;a<3;a++){
(aa => {
let test_promise = new Promise(function(resolve,reject){
    setTimeout(()=>{
        console.log("looping: " + a);
        resolve('test' + aa);
    },3000);
});

overall.push(test_promise);
})(a);
}

Promise.all(overall).then(function(value){
console.log(value);
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...