背景
<html>
<head>
<title>HTML</title>
</head>
<body>
<script src="./script1.js"></script>
<script src="./script2.js"></script>
</body>
</html>
script1
中有一個(gè)異步請(qǐng)求诵肛,script2
也想使用請(qǐng)求得到的數(shù)據(jù)。
方案
方案1:兩個(gè)腳本中分別請(qǐng)求數(shù)據(jù)
script1.js
:
const fetchRemoteData = () => {
return new Promise((resolve) => {
console.log('send request');
setTimeout(() => {
resolve({ message: 'OK' });
}, 3000);
});
};
fetchRemoteData().then((data) => {
console.log('Use data in script1', data);
});
scripts.js
:
fetchRemoteData().then((data) => {
console.log('Use data in script2', data);
});
這里用 fetchRemoteData
表示接口請(qǐng)求轴总。
上述寫(xiě)法會(huì)導(dǎo)致請(qǐng)求發(fā)送兩次。
方案2:script2
檢查數(shù)據(jù)是否準(zhǔn)備好
script1
:
const fetchRemoteData = () => {
return new Promise((resolve, reject) => {
console.log('send request');
setTimeout(() => {
resolve({ message: 'OK' });
}, 3000);
});
};
let savedData = null;
fetchRemoteData().then((data) => {
savedData = data;
console.log('Use data in script1', data);
});
script2
:
const checkInterval = setInterval(() => {
if (savedData) {
console.log('Use data in script2', savedData);
clearInterval(checkInterval);
}
}, 100);
只發(fā)送一次請(qǐng)求博个,script2
中的數(shù)據(jù)獲取性能較差怀樟。
方案3:數(shù)據(jù)檢測(cè)和回調(diào)方式
script1
:
const fetchRemoteData = () => {
return new Promise((resolve, reject) => {
console.log('send request');
setTimeout(() => {
resolve({ message: 'OK' });
}, 3000);
});
};
const whenDataReady = (() => {
let savedData = null;
let callbacks = [];
fetchRemoteData().then((data) => {
savedData = data;
while (callbacks.length) {
const callback = callbacks.pop();
callback(savedData);
}
});
return (callback) => {
if (savedData) {
callback(savedData);
} else {
callbacks.push(callback);
}
};
})();
whenDataReady((data) => {
console.log('Use data in script1', data);
});
script2
:
whenDataReady((savedData) => {
console.log('Use data in script2', savedData);
});
只發(fā)送一次請(qǐng)求。
方案4:共享 promise 對(duì)象
script1
:
const fetchRemoteData = () => {
return new Promise((resolve, reject) => {
console.log('send request');
setTimeout(() => {
resolve({ message: 'OK' });
}, 3000);
});
};
const fetchRemoteDataPromise = fetchRemoteData();
fetchRemoteDataPromise.then((data) => {
console.log('Use data in script1', data);
});
script2
:
fetchRemoteDataPromise.then((data) => {
console.log('Use data in script2', data);
});
只發(fā)送一次請(qǐng)求盆佣。
總結(jié)
實(shí)際應(yīng)用場(chǎng)景
- 模塊化開(kāi)發(fā)時(shí)往堡,異步數(shù)據(jù)在模塊之間共享。
- 兩個(gè)腳本依賴同一個(gè)異步數(shù)據(jù)共耍。
- 提供組件虑灰,組件中需要先請(qǐng)求到數(shù)據(jù),再進(jìn)行后面的操作痹兜。(建議使用方案3)
不適用的場(chǎng)景
- 數(shù)據(jù)實(shí)時(shí)性要求高穆咐,需要每次請(qǐng)求到新數(shù)據(jù)。