Это может быть больше связано с моим непониманием некоторых основ JS, однако это в контексте ethereum/web3, так что вот оно.
У меня есть записи публичного массива в моем контракте и глобальная переменная в JS с тем же именем.
Используя структуру трюфеля/пудинга во внешнем интерфейсе, я затем пытаюсь выполнить итерацию по массиву, делая что-то вроде этого:
length = 3;
posts = new Array(length);
for(i = 0; i < length; i++ ){
social.posts.call(i).then(function(v){
posts[i] = v;
});
}
Однако путем отладки я обнаружил, что анонимная функция выполняется только один раз и при i равном 3 . posts[3] устанавливается и больше ничего. Должно быть, я делаю что-то глупое здесь. Пожалуйста помоги.
Изменить: теперь я понимаю, что проблема связана с обещаниями, но есть ли другой способ легко получить значения массива из контракта? Пудинг должен был помочь в этом.
Проблема является результатом использования обещания Javascript (предоставленного Pudding), которое оборачивает вызов. Если вы сделаете тот же вызов без оболочки Promise, он будет работать так, как вы ожидаете. Но в вашем случае Обещание не разрешается, пока вы не дойдете до конца цикла.
Ты можешь сделать:
var posts = [0,1,2,3].map(index => social.posts.call(index));
Promise.map(posts, post => {
// Resolved Post Value
console.log(post);
})
Promise.all(posts).then(posts => { ... })
никогда не слышал о структуре трюфель/пудинг. Но я предполагаю, что это проблема закрытия.
значение i в анонимной функции происходит от значения i вне анонимной функции. Для каждой анонимной функции существует объект Closure, который содержит переменные, используемые анонимной функцией, где эти переменные не являются глобальными и не локальными. Итак, я предполагаю, что этот фрагмент кода находится внутри какой-то другой функции. Давайте вызовем эту другую функцию A. Когда значение переменной i изменяется внутри функции A, тогда изменяются значения ВСЕХ переменных i в замыканиях. Поскольку анонимная функция выполняется после завершения выполнения функции A, они используют значение i = 3. Одно из решений состоит в том, чтобы поместить IFFE вокруг анонимной функции и передать значение i в IFFE. Тогда значение переменной i для каждой анонимной функции не изменится после первого присвоения значения i в анонимной функции.
{(function(v){ posts[i] = v; })(i)}
но это неверно, поскольку значение v теперь не вводится в функцию, а i передается как v. Следовательно, есть ли способ сделать это с таким закрытием?
md2312