В настоящее время я работаю над проектом, который использует Javascript, Async / Await и Web3 (для Ethereum). Я хочу создать интерфейсную страницу, которая способна обнаруживать адрес метамаски пользователя, а затем использовать его в функции. У меня уже есть что-то подобное для работы на предыдущей странице, но у меня возникли проблемы с переводом на другую страницу. Я подозреваю, что getCurrentAccount () ничего не возвращает, таким образом нарушая количество и тип переменных, которые Promise.all ожидает отправить. Соответствующий код:
function isInList(input) {
return new Promise(function(resolve, reject) {
myElection.areYouInList(input, function(error, response) {
if (error) {
reject(error);
} else {
resolve(response);
}
})
});
}
function hasntVotedYet(input) {
return new Promise(function(resolve, reject) {
myElection.haveYouVotedAlready(input, function(error, response) {
if (error) {
reject(error);
} else {
resolve(response);
}
})
});
}
function isNotOver() {
return new Promise(function(resolve, reject) {
myElection.isItOver(function(error, response) {
if (error) {
reject(error)
} else {
resolve(response);
}
})
});
}
async function getCurrentAccount() {
console.info("getCurrentAccount method");
web3.eth.getAccounts((err, accounts) => {
currentAccount = accounts[0]
})
return currentAccount; //KEEP IN MIND THAT YOU NEED TO ACTUALLY BE LOGGED INTO METAMASK FOR THIS TO WORK - OTHERWISE IT'LL RETURN UNDEFINED BECAUSE THERE AREN'T ANY ACCOUNTS
}
async function verify() {
console.info("Verify");
try {
-- -- > THIS LINE //
var myCurrentAccount = await getCurrentAccount();
console.info("myCurrentAccount is: " + myCurrentAccount);
data = await Promise.all([isInList(myCurrentAccount), hasntVotedYet(myCurrentAccount), isNotOver()]); //data then equals an array, containing both the strings returned from these two methods
console.info("success");
console.info(data)
if (data[0] && !data[1] && !data[2]) { //check firstly that we are allowed to vote, secondly that we have not already voted, and finally that this vote is not over yet
var x = document.getElementById("hidden");
x.style.display = "block";
} else if (!data[0]) {
alert("That address was not found in the Whitelist.");
} else if (data[1]) {
alert("You have already voted and may not vote a second time");
} else if (data[2]) {
alert("This election has already concluded. Votes can no longer validly be cast for it.");
}
} catch (error) {
console.info("Promise.all finished with error " + error)
}
}
Не забудьте объявить свои переменные типа currentAccount или data с помощью var (или let или const). Кстати, подумайте об использовании деструктуризации для data, чтобы вы могли дать значимые имена трем значениям, которые вы ожидали.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Проблема связана с тем, как вы получаете учетную запись метамаски: web3.eth.getAccounts - это асинхронная функция. Что-то вроде этого должно работать:
async function getCurrentAccount() {
console.info("getCurrentAccount method");
let accounts = await web3.eth.getAccounts();
return accounts[0];
}
Асинхронность не означает, что она возвращает обещание и может быть обработана await. В исходном коде требуется обратный вызов ?!
да, но возврат запускается перед обратным вызовом, поэтому исходная функция getCurrentAccount возвращает undefined
И ваша тоже, если web3.eth.getAccounts ничего не возвращает (потому что ожидает обратного вызова)?
Почему
getCurrentAccount- этоasync function, если он ничего неawait? Также похоже, чтоweb3.eth.getAccountsдействительно вызывает свой обратный вызов асинхронно, поэтому вам нужно будет обещать его с помощьюnew Promise, как вы делали с тремя другими функциями раньше.