При первом вызове вместо этого назначьте Обещание, а при дальнейших вызовах верните это Обещание:
let userProm = null;
let getUser = () => {
if (!userProm) {
userProm = getUserSomehow();
}
return userProm;
};
Еще лучше, область действия userProm
только внутри getUser
, чтобы быть более безопасной иясно:
const getUser = (() => {
let userProm = null;
return () => {
if (!userProm) {
userProm = getUserSomehow();
}
return userProm;
};
})();
const getUserSomehow = () => {
console.log('getting user');
return Promise.resolve('data');
};
const getUser = (() => {
let userProm = null;
return () => {
if (!userProm) {
userProm = getUserSomehow();
}
return userProm;
};
})();
(async () => {
const userProm1 = getUser();
const userProm2 = getUser();
Promise.all([userProm1, userProm2]).then(() => {
console.log('All done');
});
})();
Ваш существующий код считается безопасным, поскольку присвоение user
произойдет до того, как первый вызов getUser
завершится:
const getUserSomehow = () => {
console.log('Getting user');
return Promise.resolve('data');
};
let user = null;
let getUser = async() => {
if (!user) {
user = await getUserSomehow();
}
return user;
};
(async () => {
let u1 = await getUser();
let u2 = await getUser();
console.log('Done');
})();
Но не было бы, если Обещания были инициализированы параллельно, до того, как одно из них было await
подготовлено к завершению первым:
const getUserSomehow = () => {
console.log('Getting user');
return Promise.resolve('data');
};
let user = null;
let getUser = async() => {
if (!user) {
user = await getUserSomehow();
}
return user;
};
(async() => {
let u1Prom = getUser();
let u2Prom = getUser();
await Promise.all([u1Prom, u2Prom]);
console.log('Done');
})();
Как показано выше, назначение Promise для постоянной переменной (вместо await
значение внутри getUser
) исправляет это.