【发布时间】:2021-07-23 13:41:21
【问题描述】:
我正在制作一个具有多个使用 IndexDB 的功能的服务工作者。在这些函数中,我收到了这些打字稿错误:
Property 'errorCode' does not exist on type 'EventTarget'
当使用db.onsuccess & db.onerror时
这是我的服务工作者代码:
/// <reference no-default-lib="true"/>
/// <reference lib="ES2020" />
/// <reference lib="dom" />
/// <reference lib="dom.iterable" />
/// <reference lib="webworker" />
export type {};
declare const self: ServiceWorkerGlobalScope;
interface AccessCredentials {
accessToken: string;
refreshToken: string;
}
async function getAccessCredentials(): Promise<AccessCredentials> {
const databaseName = 'BATAccessTokens';
const databaseStore = 'BATAccessTokens';
return new Promise((resolve, reject) => {
const dbrequest = indexedDB.open(databaseName, 1);
dbrequest.onupgradeneeded = (event) => {
const database = dbrequest.result;
database.createObjectStore(databaseStore, { autoIncrement: true });
database.onerror = () =>
reject(`ERROR: ${event.target.errorCode}`);
};
dbrequest.onerror = (event) =>
reject(`ERROR: ${event.target.errorCode}`);
dbrequest.onsuccess = (event) => {
const database = dbrequest.result;
const transaction = database.transaction(databaseStore, 'readwrite');
const store = transaction.objectStore(databaseStore);
const request = store.get(1);
request.onsuccess = () => {
if (request.result) resolve(request.result);
resolve(null);
};
transaction.oncomplete = () => database.close();
database.onerror = () => resolve(null);
};
});
}
async function putAccessCredentials(credentials: AccessCredentials) {
const databaseName = 'BATAccessTokens';
const databaseStore = 'BATAccessTokens';
return new Promise((resolve, reject) => {
const dbrequest = indexedDB.open(databaseName, 1);
dbrequest.onupgradeneeded = () => {
const database = dbrequest.result;
database.createObjectStore(databaseStore, { autoIncrement: true });
database.onerror = (event) =>
reject(`ERROR: ${event.target.errorCode}`);
};
dbrequest.onerror = (event) =>
reject(`ERROR: ${event.target.errorCode}`);
dbrequest.onsuccess = (event) => {
const database = dbrequest.result;
const transaction = database.transaction(databaseStore, 'readwrite');
const store = transaction.objectStore(databaseStore);
const request = store.put(credentials, 1);
request.onsuccess = () => resolve(credentials);
transaction.oncomplete = () => database.close();
database.onerror = () =>
reject(`ERROR: ${event.target.errorCode}`);
};
});
}
async function putRBDSCode(RBDSCode) {
const databaseName = 'BATRBDSCode';
const databaseStore = 'BATRBDSCode';
return new Promise((resolve, reject) => {
const dbrequest = indexedDB.open(databaseName, 1);
dbrequest.onupgradeneeded = () => {
const database = dbrequest.result;
database.createObjectStore(databaseStore, { autoIncrement: true });
database.onerror = (event) =>
reject(`ERROR: ${event.target.errorCode}`);
};
dbrequest.onerror = (event) =>
reject(`ERROR: ${event.target.errorCode}`);
dbrequest.onsuccess = (event) => {
const database = dbrequest.result;
const transaction = database.transaction(databaseStore, 'readwrite');
const store = transaction.objectStore(databaseStore);
const request = store.put(RBDSCode, 1);
request.onsuccess = () => resolve(RBDSCode);
transaction.oncomplete = () => database.close();
database.onerror = () =>
reject(`ERROR: ${event.target.errorCode}`);
};
});
}
async function getClientList(): Promise<readonly WindowClient[]> {
const clientList = await self.clients.claim().then(() =>
self.clients.matchAll({
type: 'window'
})
);
return clientList;
}
self.addEventListener('install', (event) => {
console.log('Service Worker installed');
});
self.addEventListener('activate', (event) => {
console.log('Service Worker activated');
});
self.addEventListener('fetch', (event) => {
if (event.request.method === 'GET' && event.request.mode === 'navigate') {
let request = event.request;
// console.log({request});
event.waitUntil(getClientList());
event.respondWith((async () => {
const clientList = await getClientList();
const client = clientList.find((item) => item.visibilityState === 'visible');
const url = client && new URL(client.url);
const rbdsCode = url && url.searchParams.get('RBDSCode');
const credentials = await getAccessCredentials();
const dppRequest = false;
const rbdsRequest = !!rbdsCode && !dppRequest;
if (rbdsRequest && !credentials) {
// console.log(client);
// client.navigate('/forms/login.html').then(() => client.focus())
request = new Request(`http://localhost:3000/forms/login.html`);
}
if (request && credentials) {
// do something
}
if (dppRequest) {
// handle dpp request
}
if (credentials) request = new Request(request, {
headers: {
...request.headers,
Authorization: `Bearer ${credentials.accessToken}`
}
});
const eventResponse = await fetch(request).then((response) => {
let accessToken, refreshToken;
for (const header of response.headers.entries()) {
if (header[0] === 'accesstoken') accessToken = header[1];
if (header[0] === 'refreshtoken') refreshToken = header[1];
}
accessToken && refreshToken && putAccessCredentials({ accessToken, refreshToken });
return response;
});
return eventResponse;
})());
}
});
【问题讨论】:
-
将
errorCode更改为error有什么不同吗?我问是因为IDBRequest.onerror 下显示的示例使用属性名称error来获取更多信息 - 并假设error.target指的是设置.onerror的(请求)对象。 -
否,因为这里的函数参数输入到事件,但是我想我找到了使用
dbrequest.error.code的解决方法 -
小心你使用的 typescript 声明文件,许多 typescript 库对 IndexedDB 的类型声明不正确
标签: javascript typescript service-worker indexeddb