Browse Source

Merge pull request #27 from zzarcon/finally_job_method

Implement "finally" TesseractJob method
pull/34/head
Kevin Kwok 8 years ago committed by GitHub
parent
commit
b20c4a8c6e
  1. 26
      README.md
  2. 12
      examples/node/basic.js
  3. 81
      src/common/job.js
  4. 72
      src/index.js

26
README.md

@ -60,6 +60,7 @@ You can [head to the docs](#docs) for a full treatment of the API. @@ -60,6 +60,7 @@ You can [head to the docs](#docs) for a full treatment of the API.
+ [TesseractJob.progress(callback: function) -> TesseractJob](#tesseractjobprogresscallback-function---tesseractjob)
+ [TesseractJob.then(callback: function) -> TesseractJob](#tesseractjobthencallback-function---tesseractjob)
+ [TesseractJob.catch(callback: function) -> TesseractJob](#tesseractjoberrorcallback-function---tesseractjob)
+ [TesseractJob.finally(callback: function) -> TesseractJob](#tesseractjobfinallycallback-function---tesseractjob)
* [Local Installation](#local-installation)
+ [corePath](#corepath)
+ [workerPath](#workerpath)
@ -80,7 +81,7 @@ Figures out what words are in `image`, where the words are in `image`, etc. @@ -80,7 +81,7 @@ Figures out what words are in `image`, where the words are in `image`, etc.
+ include properties that override some subset of the [default tesseract parameters](./docs/tesseract_parameters.md)
+ include a `lang` property with a value from the [list of lang parameters](./docs/tesseract_lang_list.md)
Returns a [TesseractJob](#tesseractjob) whose `then`, `progress`, and `catch` methods can be used to act on the result.
Returns a [TesseractJob](#tesseractjob) whose `then`, `progress`, `catch` and `finally` methods can be used to act on the result.
### Simple Example:
```javascript
@ -111,7 +112,7 @@ Figures out what script (e.g. 'Latin', 'Chinese') the words in image are writte @@ -111,7 +112,7 @@ Figures out what script (e.g. 'Latin', 'Chinese') the words in image are writte
- `image` is any [ImageLike](#imagelike) object.
Returns a [TesseractJob](#tesseractjob) whose `then`, `progress`, and `error` methods can be used to act on the result of the script.
Returns a [TesseractJob](#tesseractjob) whose `then`, `progress`, `error` and `finally` methods can be used to act on the result of the script.
```javascript
@ -146,25 +147,28 @@ In NodeJS, an image can be @@ -146,25 +147,28 @@ In NodeJS, an image can be
## TesseractJob
A TesseractJob is an an object returned by a call to `recognize` or `detect`. It's inspired by the ES6 Promise interface and provides `then` and `catch` methods. One important difference is that these methods return the job itself (to enable chaining) rather than new.
A TesseractJob is an an object returned by a call to `recognize` or `detect`. It's inspired by the ES6 Promise interface and provides `then` and `catch` methods. It also provides `finally` method, which will be fired regardless of the job fate. One important difference is that these methods return the job itself (to enable chaining) rather than new.
Typical use is:
```javascript
Tesseract.recognize(myImage)
.progress(function(message){console.log(message)})
.catch(function(err){console.error(err)})
.then(function(result){console.log(result)})
.progress(message => console.log(message))
.catch(err => console.error(err))
.then(result => console.log(result))
.finally(resultOrError => console.log(resultOrError))
```
Which is equivalent to:
```javascript
var job1 = Tesseract.recognize(myImage);
job1.progress(function(message){console.log(message)});
job1.progress(message => console.log(message));
job1.catch(function(err){console.error(err)});
job1.catch(err => console.error(err));
job1.then(function(result){console.log(result)})
job1.then(result => console.log(result));
job1.finally(resultOrError => console.log(resultOrError));
```
@ -225,6 +229,10 @@ result is: { @@ -225,6 +229,10 @@ result is: {
Sets `callback` as the function that will be called if the job fails.
- `callback` is a function with the signature `callback(error)` where `error` is a json object.
### TesseractJob.finally(callback: function) -> TesseractJob
Sets `callback` as the function that will be called regardless if the job fails or success.
- `callback` is a function with the signature `callback(resultOrError)` where `resultOrError` is a json object.
## Local Installation
In the browser, `tesseract.js` simply provides the API layer. Internally, it opens a WebWorker to handle requests. That worker itself loads code from the Emscripten-built `tesseract.js-core` which itself is hosted on a CDN. Then it dynamically loads language files hosted on another CDN.

12
examples/node/basic.js

@ -3,6 +3,12 @@ var Tesseract = require('../../') // replace this with require('tesseract.js') @@ -3,6 +3,12 @@ var Tesseract = require('../../') // replace this with require('tesseract.js')
var image = path.resolve(__dirname, 'cosmic.png');
Tesseract.recognize(image)
.then(function(data){
console.log(data.text)
})
.then(data => {
console.log('then\n', data.text)
})
.catch(err => {
console.log('catch\n', err);
})
.finally(data => {
console.log('finally\n', data.text);
});

81
src/common/job.js

@ -0,0 +1,81 @@ @@ -0,0 +1,81 @@
const adapter = require('../node/index.js')
let jobCounter = 0;
module.exports = class TesseractJob {
constructor(instance){
this.id = 'Job-' + (++jobCounter) + '-' + Math.random().toString(16).slice(3, 8)
this._instance = instance;
this._resolve = []
this._reject = []
this._progress = []
this._finally = []
}
then(resolve, reject){
if(this._resolve.push){
this._resolve.push(resolve)
}else{
resolve(this._resolve)
}
if(reject) this.catch(reject);
return this;
}
catch(reject){
if(this._reject.push){
this._reject.push(reject)
}else{
reject(this._reject)
}
return this;
}
progress(fn){
this._progress.push(fn)
return this;
}
finally(fn) {
this._finally.push(fn)
return this;
}
_send(action, payload){
adapter.sendPacket(this._instance, {
jobId: this.id,
action: action,
payload: payload
})
}
_handle(packet){
var data = packet.data;
let runFinallyCbs = false;
if(packet.status === 'resolve'){
if(this._resolve.length === 0) console.debug(data);
this._resolve.forEach(fn => {
var ret = fn(data);
if(ret && typeof ret.then == 'function'){
console.warn('TesseractJob instances do not chain like ES6 Promises. To convert it into a real promise, use Promise.resolve.')
}
})
this._resolve = data;
this._instance._dequeue()
runFinallyCbs = true;
}else if(packet.status === 'reject'){
if(this._reject.length === 0) console.error(data);
this._reject.forEach(fn => fn(data))
this._reject = data;
this._instance._dequeue()
runFinallyCbs = true;
}else if(packet.status === 'progress'){
this._progress.forEach(fn => fn(data))
}else{
console.warn('Message type unknown', packet.status)
}
if (runFinallyCbs) {
this._finally.forEach(fn => fn(data));
}
}
}

72
src/index.js

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
const adapter = require('./node/index.js')
const circularize = require('./common/circularize.js')
const TesseractJob = require('./common/job');
const objectAssign = require('object-assign');
function create(workerOptions){
@ -75,75 +76,6 @@ class TesseractWorker { @@ -75,75 +76,6 @@ class TesseractWorker {
}
}
var jobCounter = 0;
class TesseractJob {
constructor(instance){
this.id = 'Job-' + (++jobCounter) + '-' + Math.random().toString(16).slice(3, 8)
this._instance = instance;
this._resolve = []
this._reject = []
this._progress = []
}
then(resolve, reject){
if(this._resolve.push){
this._resolve.push(resolve)
}else{
resolve(this._resolve)
}
if(reject) this.catch(reject);
return this;
}
catch(reject){
if(this._reject.push){
this._reject.push(reject)
}else{
reject(this._reject)
}
return this;
}
progress(fn){
this._progress.push(fn)
return this;
}
_send(action, payload){
adapter.sendPacket(this._instance, {
jobId: this.id,
action: action,
payload: payload
})
}
_handle(packet){
var data = packet.data;
if(packet.status === 'resolve'){
if(this._resolve.length === 0) console.debug(data);
this._resolve.forEach(fn => {
var ret = fn(data);
if(ret && typeof ret.then == 'function'){
console.warn('TesseractJob instances do not chain like ES6 Promises. To convert it into a real promise, use Promise.resolve.')
}
})
this._resolve = data;
this._instance._dequeue()
}else if(packet.status === 'reject'){
if(this._reject.length === 0) console.error(data);
this._reject.forEach(fn => fn(data))
this._reject = data;
this._instance._dequeue()
}else if(packet.status === 'progress'){
this._progress.forEach(fn => fn(data))
}else{
console.warn('Message type unknown', packet.status)
}
}
}
var DefaultTesseract = create()
module.exports = DefaultTesseract
module.exports = DefaultTesseract
Loading…
Cancel
Save