Как правильно использовать async/await?
Мне нужно что бы функции отработали в соответствии с порядком вызова. Добавил async/await но, это не помогло. Как его правильно использовать?
Функция analyze переберает массив и вызывает записаные в него функции и сумирует результат.
Функция initFingerprintJS должна вернуть значение,но, я з JS знаком плохо и поэтому запустался в этих callback'ах, промисах и async/await.
Поэтому решил напрямую писать в переменную.
Желаемый результат: START -> ANALYZE (c:0, c:1) -> SET ID -> ID -> END
const counters = [
function() {
return navigator.webdriver ? 5 : 0;
},
function() {
let agent = window.navigator.userAgent;
if (/headless/i.test(agent) || /PhantomJS/i.test(agent)) {
return 3;
}
return 0;
},
function() {
navigator.permissions.query({
name: 'notifications'
}).then(function(permissionStatus) {
if (Notification.permission === 'denied' && permissionStatus.state === 'prompt') {
return 10;
}
});
return 0;
}
];
let id;
window.addEventListener('DOMContentLoaded', async function() {
console.log('START');
let res = await analyze();
initFingerprintJS();
console.log('ID: ' + id);
console.log('END');
});
async function analyze() {
let r = 0;
counters.forEach((v, k) => {
console.log('c: ' + k);
r += v();
});
return r;
}
function initFingerprintJS() {
let fpPromise =
import ('https://openfpcdn.io/fingerprintjs/v3')
.then(FingerprintJS => FingerprintJS.load({
region: 'eu'
}));
fpPromise
.then(fp => fp.get())
.then(result => {
console.log('SET ID');
id = result.visitorId;
});
}
Ответы (1 шт):
сам по себе async ничего не дает. Для правильной работы нужно расставить еще и await.
Для того чтобы использовать await функция должна возвращать Promise, который и будет ожидаться.
В коде в вопросе ни одна из функций не возвращает Promise, соответственно и дождаться выполнения невозможно.
Самое простое решения для initFingerprintJS. Достаточно добавить return.
return fpPromise
Две оставшиеся функции нужно переделать так, чтобы они возвращали Promise.
На примере с setTimeout.
function analyze() {
return new Promise(r => // создаем новый Promise
setTimeout(
() => r(console.log('ANALYZE')), // вызываем `r` переводя `Promise` в состояние resolved
1000));
}
Теперь в основной функции нужно добавить недостающие await
await setFingerPrint();
Так как в analyze нет асинхронных операций, то нет смысла добавлять async для этой функции.
Пример в сборе:
const counters = [
function() {
return 1;
},
function() {
return 2;
}
];
let id;
window.addEventListener('DOMContentLoaded', async function() {
console.log('START');
analyze();
await setFingerPrint();
console.log('END')
});
function analyze() {
let r = 0;
counters.forEach((v, k) => {
console.log('c: ' + k);
r += v();
});
return r;
}
function setFingerPrint() {
return new Promise(r => {
if (window.requestIdleCallback) {
requestIdleCallback(() => r(initFingerprintJS()));
} else {
setTimeout(() => r(initFingerprintJS()), 500);
}
});
}
function initFingerprintJS() {
let fpPromise =
import ('https://openfpcdn.io/fingerprintjs/v3')
.then(FingerprintJS => FingerprintJS.load({
region: 'eu'
}));
return fpPromise
.then(fp => fp.get())
.then(result => {
console.log('SET ID');
});
}