今天一同事问我Jscex怎么没有stop啊?
异步任务就像断线的风筝,我们没法让它说停就停,但是我们在放飞它之前,可以装个定时炸弹。
通常我们可以这样退出一个异步任务:
var xxxAsync = eval(Jscex.compile("async", function () {
while (condition) {
....
dosomething
....
$await(Jscex.Async.sleep(1000));
}
}))
通过condition判断是否退出异步任务。或者等同于下面这种方式:
var xxxAsync = eval(Jscex.compile("async", function () {
while (true) {
if(condition)break;
....
dosomething
....
$await(Jscex.Async.sleep(1000));
}
}))
这两种方式的效果是一模一样的。
下面这种方式有个好处就是可以做一些初始化设置什么的:
var xxxAsync = eval(Jscex.compile("async", function () {
while (true) {
if (condition) {
//dosomething
break;
}
//dosomething
$await(Jscex.Async.sleep(1000));
}
}))
后来,同事又提供了一个要跳出循环的场景
var xxxAsync = eval(Jscex.compile("async", function () {
while (true) {
for (i in XXX) {
if (condition) {
//要在这里跳出最外层的循环
}
}
//dosomething
$await(Jscex.Async.sleep(1000));
}
}))
所以就只能这样:
var xxxAsync = eval(Jscex.compile("async", function () {
while (true) {
for (i in XXX) {
if (condition) {
//要在这里跳出最外层的循环
breakTag = true;
}
}
if (breakTag) break;
//dosomething
$await(Jscex.Async.sleep(1000));
}
}))
后来同事又提供了一个BT的场景:
var countAsync1 = eval(Jscex.compile("async", function () {
while (true) {
for (i in XXX) {
if (condition) {
//要在这里跳出最外层的循环
}
}
$await(Jscex.Async.sleep(1000));
}
}))
var countAsync2 = eval(Jscex.compile("async", function () {
while (true) {
for (i in XXX) {
if (condition) {
//要在这里跳出最外层的循环
}
}
$await(Jscex.Async.sleep(1000));
}
}))
var executeAsyncQueue = eval(Jscex.compile("async", function () {
while (true) {
$await(countAsync1())
$await(countAsync2())
$await(Jscex.Async.sleep(1000));
}
}))
executeAsyncQueue().start();
相当于要在异步队列中跳出最最外层的循环。
我给出的方案还是breakTag
var executeAsyncQueue = eval(Jscex.compile("async", function () {
while (true) {
$await(countAsync1())
$await(countAsync2())
if (breakTag) break;
$await(Jscex.Async.sleep(1000));
}
}))
同理这个场景也用tag:
var xxAsync = eval(Jscex.compile("async", function () {
while (true) {
//dosomething
$await(xxxAsync())
if (breakTag) break;
$await(Jscex.Async.sleep("1000"));
}
}))
var xxxAsync = eval(Jscex.compile("async", function () {
if (condition) {
breakTag = true;
}
$await(Jscex.Async.sleep("1000"));
}))
所以:Jscex没有必要提供stop,你说呢?
Jscex.Async.Task = function (delegate) {
this._delegate = delegate;
this._handlers = [];
this.status = "ready";
}
Jscex.Async.Task.prototype = {
start: function () {
if (this.status != "ready") {
throw 'Task can only be started in "ready" status.';
}
var _this = this;
this.status = "running";
this._delegate["onStart"](function (type, value) {
if (_this.status != "running") {
throw ('Callback can only be used in "running" status.');
}
if (type == "success") {
_this.result = value;
_this.status = "succeeded";
} else if (type == "failure") {
_this.error = value;
_this.status = "failed";
} else if (type == "cancel") {
_this.status = "canceled";
} else {
throw ("Unsupported type: " + type);
}
_this._notify();
});
},
cancel: function () {
if (this.status != "running") {
throw 'Task can only be canceled in "running" status';
}
var onCancel = this._delegate["onCancel"];
if (onCancel) onCancel();
this._notify();
},
_notify: function () {
var handlers = this._handlers;
delete this._handlers;
for (var i = 0; i < handlers.length; i++) {
handlers[i](this);
}
},
addListener: function (handler) {
if (!this._handlers) {
throw ('Listeners can only be added in "ready" or "running" status.');
}
this._handlers.push(handler);
}
};