我有一些服务器API方法,它们是在我的应用程序启动时在不同位置调用的,无法根据调用位置进行重构,例如getSettings()
和getSchedule()
。两种方法都基于login(): Promise<Account>
方法,设置和计划都是基于用户的。
现在我已经像下面这样解决了getSettings()
和getSchedule()
的开头:
class UserFunctions {
private fetch_login: Promise<AccountItem> = undefined;
async getSchedule(): Promise<any> {
var account = getAccount();
if (!account) {
// No account loaded
let isLogginIn = this.fetch_login;
if (!this.fetch_login) {
// Not logging in from any parallel method
this.fetch_login = login();
}
account = await this.fetch_login;
this.fetch_login = undefined;
}
// Now get schedule...
}
}
其背后的想法是login()
函数仅被调用一次,无论它被调用的频率如何。这就是为什么我会在Promise上保留多次引用的原因。此方法有效,但我注意到有时login()
完成后getSettings()
可以继续工作,并且getSchedule()
停留几秒钟直到它继续执行。有时是另一回事,有时两个方法会同时返回。
我在这里打印输出:
06-05 16:46:08.126 27376 27397我ReactNativeJS:重新登录
06-05 16:46:08.690 27376 27397我ReactNativeJS:重新登录
06-05 16:46:08.696 27376 27397 I ReactNativeJS:时间表已下载
06-05 16:46:09.274 27376 27397我ReactNativeJS:重新登录
您是否知道一旦login()
完成后,两种方法都能继续工作,如何改进代码?
答案 0 :(得分:1)
我认为您有一个正确的主意,但是逻辑上需要一些调整:
var account = getAccount();
if (!account) {
// No account loaded
if (!this.fetch_login) {
// Not logging in from any parallel method
this.fetch_login = login();
}
account = await this.fetch_login;
}
基本上,您的想法是将fetch_login
设置为在首次调用诺言时具有诺言的值。之后,您可以根据需要await
多次进行相同的承诺。
答案 1 :(得分:0)
两件事:
您正在正在呼叫 fetch_login
。您应该只是在引用它:
account = await this.fetch_login; // <== No ()
删除此行:
this.fetch_login = undefined;
例如:
async getSchedule(): Promise<any> {
var account = getAccount();
if (!account) {
// No account loaded
if (!this.fetch_login) {
// Not logging in from any parallel method
this.fetch_login = login();
}
account = await this.fetch_login;
}
// Now get schedule...
}
您保留登录尝试产生的承诺,因此您可以每次await
。 (await
作出承诺不会阻止您再次这样做。)
不过,似乎应该在getAccount
和login
级别上进行处理,而不是在UserFunctions
内进行处理。 getAccount
和login
似乎是全局的(在您的应用程序或模块或任何其他内部)。我可能会让他们来管理,getAccount
返回一个诺言:
var accountPromise = null;
function getAccount() {
if (!accountPromise) {
accountPromise = login();
}
return accountPromise;
}
然后
async getSchedule(): Promise<any> {
var account = await getAccount();
// Now get schedule...
}
示例:
var accountPromise = null;
function getAccount() {
if (!accountPromise) {
accountPromise = login();
}
return accountPromise;
}
function login() {
return new Promise(resolve => {
console.log("Logging in...");
setTimeout(() => {
console.log("Logged in");
resolve({}); // {} = the account
}, 800);
});
}
class UserFunctions {
/*private*/ fetch_login/*: Promise<AccountItem>*/ = undefined;
async getSchedule()/*: Promise<any>*/ {
var account = await getAccount();
// Now get schedule...
console.log("Got account, getting schedule");
}
}
// The first time it's used
const u1 = new UserFunctions();
u1.getSchedule(); // Logs in and gets schedule
// The second time it's used
setTimeout(() => {
const u2 = new UserFunctions();
u2.getSchedule(); // Gets schedule (already logged in)
}, 2000);