新增 特性continuation

This commit is contained in:
hyb1996
2018-12-09 16:53:10 +08:00
parent 8b907d31c8
commit 8faa6cc990
2 changed files with 131 additions and 0 deletions

View File

@@ -0,0 +1,48 @@
module.exports = function (runtime, global) {
const Continuation = com.stardust.autojs.rhino.continuation.Continuation;
function continuation() {
}
continuation.create = function (scope) {
scope = scope || global;
var cont = Object.create(runtime.createContinuation(scope));
cont.await = function () {
let result = cont.suspend();
if (result.error != null) {
throw result.error;
}
return result.result;
};
cont.resumeError = function (error) {
if (error == null || error == undefined) {
throw TypeError("error is null or undefined");
}
cont.resumeWith(Continuation.Result.Companion.failure(error));
}
cont.resume = function (result) {
cont.resumeWith(Continuation.Result.Companion.success(result));
}
return cont;
}
function awaitPromise(scope, promise) {
var cont = continuation.create(scope);
promise.then(result => {
cont.resume(result);
}).catch(error => {
cont.resumeError(error);
});
return cont.await();
}
continuation.await = function (any) {
if (Object.getPrototypeOf(any).constructor === Promise) {
return awaitPromise(global, any);
}
throw new TypeError('cannot await ' + any);
}
return continuation;
}

View File

@@ -0,0 +1,83 @@
function ResultAdapter() {
if (ui.isUiThread()) {
this.cont = continuation.create();
this.impl = {
setResult: (result) => {
this.cont.resume(result);
},
setError: (error) => {
this.cont.resumeError(error);
},
get: () => {
return this.cont.await();
}
};
} else {
this.disposable = threads.disposable();
this.impl = {
setResult: (result) => {
this.disposable.setAndNotify({ result: result });
},
setError: (error) => {
this.disposable.setAndNotify({ error: error });
},
get: () => {
let result = this.disposable.blockedGet();
return getOrThrow(result);
}
};
}
}
function getOrThrow(result) {
if (result.error) {
throw result.error;
}
return result.result;
}
ResultAdapter.prototype.setResult = function (result) {
this.impl.setResult(result);
}
ResultAdapter.prototype.setError = function (error) {
this.impl.setError(error);
}
ResultAdapter.prototype.callback = function () {
var that = this;
return function (result, error) {
if(that.result !== undefined){
that.result = {
result: result,
error: error
};
return;
}
if (error) {
that.setError(error);
} else {
that.setResult(result);
}
};
}
ResultAdapter.prototype.get = function () {
if(this.result){
return getOrThrow(this.result);
}
this.result = null;
return this.impl.get();
}
ResultAdapter.promise = function(promiseAdapter) {
return new Promise(function(resolve, reject){
promiseAdapter.onResolve(function(result) {
resolve(result);
}).onReject(function(error){
reject(error);
});
})
}
module.exports = ResultAdapter;