Skip to content

Instantly share code, notes, and snippets.

@JacksonTian
Last active June 28, 2016 01:40
Show Gist options
  • Save JacksonTian/4362563 to your computer and use it in GitHub Desktop.
Save JacksonTian/4362563 to your computer and use it in GitHub Desktop.
Go语言的actor并发模式更容易,一点都不绕,比如要实现一个API,API内部有两个http接口A,B并发调用,如果都在200ms内返回,则合并结果输出,如果B比A慢,且B耗时超过200ms,则丢弃B调用只返回A结果;用Go很容易实现这个逻辑,50行 - 牛,学到了,但看逻辑是不是A和B如果都超过200ms了就无结果输出?这种情况下需要等A返回了再返回 - 逻辑还可以再完善一下,如果ab都在200ms内返回应该在慢的那个返回时就触发,而不是等到200ms - 接着上面的需求,如果B之后还要根据B的结果来判断是否要调用C,然后B和C的结果和A join后再进入下一个阶段 用我自己的EventProxy库做了下重构 https://gist.github.com/4364823 加注释50行。
var callA = function (callback) {
setTimeout(function () {
callback({name: "a", data: "I am result A"});
}, Math.round(Math.random() * 300));
};
var callB = function (callback) {
setTimeout(function () {
callback({name: "b", data: Math.round(Math.random() * 300)) % 2 === 0});
}, Math.round(Math.random() * 300));
};
var callC = function (callback) {
setTimeout(function () {
callback({name: "c", data: "I am result C"});
}, Math.round(Math.random() * 300));
};
var api = function (callback) {
var result = {}, counter = 0, timer;
var emitter = new events.EventEmitter();
var done = function () {
clearTimeout(timer);
emitter.removeAllListeners();
if (ret.hasOwnProperty("b") && ret.b) {
callC(function (c) {
result[c.name] = c.data;
callback(result);
});
} else {
callback(result);
}
};
var emit = function (ret) {
emitter.emit('got', ret);
};
emitter.on('got', function (ret) {
result[ret.name] = ret.data;
counter++;
if (counter === 2) {
done();
}
});
callA(emit);
callB(emit);
timer = setTimeout(function () {
if (!result.hasOwnProperty('a')) {
emitter.on('got', function (ret) {
if (ret.name === 'a') {
done();
}
});
} else {
done();
}
}, 200);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment