我目前正在通过编写 chrome 扩展来练习 javascript。在这个过程中,我多次遇到这样的情况
- 从同步虚拟实现开始
- 稍后请注意,预期的最终实现需要使用异步 API。
例如,我有一个用户选项的中间实现,
function getOption(name){
return INFO[name].default;
}
但是,我想添加对与 chrome.storage.get/set
同步的支持,两者都是异步的。
通过 promise ,我可以重写该函数,例如如
function getOption(name){
return new Promise(function(resolve){
chrome.storage.sync.get(name, resolve);
}).then(function(obj){
const val = obj[name];
return val !== undefined ? val : INFO[name].default;
});
}
但是,这需要重构以显式处理使用任何选项的异步性
- 显式使用 Promise API
- 将使用选项的函数转换为
异步函数
,以便可以使用await
,这又需要将这些函数转换为同步重写等。
或者,我可以想象一些黑客解决方案,例如让后台函数定期同步选项,例如
function getOption(name){
return INFO[name].actual !== undefined
? INFO[name].actual : INFO[name].default;
}
// Sync once a minute
window.setInterval(function sync(){
chrome.storage.sync.get('THENAME', function(obj){
INFO[name].actual = obj.THENAME;
},
60*1000);
在这种特定情况下,这是可以接受的,但考虑到我对使用这种基于轮询的同步方法的程序感到沮丧,我宁愿避免它。
有没有更好的方法来处理这种情况?
最佳答案
确实没有。从同步重构为异步是一个重大变化,给整个应用程序带来震动。不过,将 Promise 与 async
/await
一起使用将具有最低的语法开销。
避免这种情况的唯一方法是从一开始就将整个应用程序设计为异步。确保在任何地方都考虑并发性(可能存在竞争条件),并在必要时强制执行序列。意识到用户选项在某个时刻(在未来的开发过程中)必须在运行时从某些存储(磁盘、网络等)动态加载 - 而不仅仅是在启动时,where we could work around this -,从异步原型(prototype)开始:
function getOption(name) {
return Promise.resolve(INFO[name].default);
}
// or
async function getOption(name) {
return INFO[name].default;
}
关于javascript - 当 JavaScript 中引入异步值时,如何最大限度地减少重构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45664758/