move anki to async

This commit is contained in:
Alex Yatskov 2017-07-10 16:24:31 -07:00
parent efb5ed2af8
commit b0cdf59bd8
4 changed files with 63 additions and 75 deletions

View File

@ -20,69 +20,50 @@
class AnkiConnect {
constructor(server) {
this.server = server;
this.asyncPools = {};
this.localVersion = 2;
this.remoteVersion = null;
this.remoteVersion = 0;
}
addNote(note) {
return this.checkVersion().then(() => this.ankiInvoke('addNote', {note}));
async addNote(note) {
await this.checkVersion();
return await this.ankiInvoke('addNote', {note});
}
canAddNotes(notes) {
return this.checkVersion().then(() => this.ankiInvoke('canAddNotes', {notes}, 'notes'));
async canAddNotes(notes) {
await this.checkVersion();
return await this.ankiInvoke('canAddNotes', {notes});
}
getDeckNames() {
return this.checkVersion().then(() => this.ankiInvoke('deckNames', {}));
async getDeckNames() {
await this.checkVersion();
return await this.ankiInvoke('deckNames');
}
getModelNames() {
return this.checkVersion().then(() => this.ankiInvoke('modelNames', {}));
async getModelNames() {
await this.checkVersion();
return await this.ankiInvoke('modelNames');
}
getModelFieldNames(modelName) {
return this.checkVersion().then(() => this.ankiInvoke('modelFieldNames', {modelName}));
async getModelFieldNames(modelName) {
await this.checkVersion();
return await this.ankiInvoke('modelFieldNames', {modelName});
}
guiBrowse(query) {
return this.checkVersion().then(() => this.ankiInvoke('guiBrowse', {query}));
async guiBrowse(query) {
await this.checkVersion();
return await this.ankiInvoke('guiBrowse', {query});
}
checkVersion() {
if (this.localVersion === this.remoteVersion) {
return Promise.resolve(true);
}
return this.ankiInvoke('version', {}, null).then(version => {
this.remoteVersion = version;
async checkVersion() {
if (this.remoteVersion < this.localVersion) {
this.remoteVersion = await this.ankiInvoke('version');
if (this.remoteVersion < this.localVersion) {
return Promise.reject('extension and plugin versions incompatible');
}
});
}
}
ankiInvoke(action, params, pool) {
return new Promise((resolve, reject) => {
if (pool && this.asyncPools.hasOwnProperty(pool)) {
this.asyncPools[pool].abort();
}
const xhr = new XMLHttpRequest();
xhr.addEventListener('loadend', () => {
if (pool) {
delete this.asyncPools[pool];
}
if (xhr.responseText) {
resolve(JSON.parse(xhr.responseText));
} else {
reject('unable to connect to plugin');
}
});
xhr.open('POST', this.server);
xhr.send(JSON.stringify({action, params}));
});
ankiInvoke(action, params) {
return jsonRequest(this.server, 'POST', {action, params, version: this.localVersion});
}
}

View File

@ -18,27 +18,27 @@
class AnkiNull {
addNote(note) {
return Promise.reject('unsupported action');
async addNote(note) {
return null;
}
canAddNotes(notes) {
return Promise.resolve([]);
async canAddNotes(notes) {
return [];
}
getDeckNames() {
return Promise.resolve([]);
async getDeckNames() {
return [];
}
getModelNames() {
return Promise.resolve([]);
async getModelNames() {
return [];
}
getModelFieldNames(modelName) {
return Promise.resolve([]);
async getModelFieldNames(modelName) {
return [];
}
guiBrowse(query) {
return Promise.resolve([]);
async guiBrowse(query) {
return [];
}
}

View File

@ -31,7 +31,7 @@ class Translator {
if (!this.deinflector) {
const url = chrome.extension.getURL('/bg/lang/deinflect.json');
const reasons = await Translator.loadRules(url);
const reasons = await jsonRequest(url, 'GET');
this.deinflector = new Deinflector(reasons);
}
}
@ -124,22 +124,4 @@ class Translator {
return definitions;
}
static loadRules(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.overrideMimeType('application/json');
xhr.addEventListener('load', () => resolve(xhr.responseText));
xhr.addEventListener('error', () => reject('failed to execute network request'));
xhr.open('GET', url);
xhr.send();
}).then(responseText => {
try {
return JSON.parse(responseText);
}
catch (e) {
return Promise.reject('invalid JSON response');
}
});
}
}

View File

@ -428,6 +428,31 @@ function dictFieldFormat(field, definition, mode, options) {
return field;
}
/*
* JSON
*/
function jsonRequest(url, action, params) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.overrideMimeType('application/json');
xhr.addEventListener('load', () => resolve(xhr.responseText));
xhr.addEventListener('error', () => reject('failed to execute network request'));
xhr.open(action, url);
if (params) {
xhr.send(JSON.stringify(params));
} else {
xhr.send();
}
}).then(responseText => {
try {
return JSON.parse(responseText);
}
catch (e) {
return Promise.reject('invalid JSON response');
}
});
}
/*
* Helpers