Skip to content

Instantly share code, notes, and snippets.

@gaogao-9
Last active July 28, 2016 08:30
Show Gist options
  • Save gaogao-9/5056d7b5b3a9b8489595cdb001302b81 to your computer and use it in GitHub Desktop.
Save gaogao-9/5056d7b5b3a9b8489595cdb001302b81 to your computer and use it in GitHub Desktop.
非同期メソッドチェーンのmixinです。
const queue = Symbol("queue");
const sync = Symbol("sync");
const createAwaiter = Symbol("createAwaiter");
const addQueue = Symbol("addQueue");
const syncMethods = Symbol("syncMethods");
const Awaiter = ((Base)=> {
class Awaiter extends Base{
constructor(...args){
super(...args);
this[queue] = this[queue] || Promise.resolve();
this[createAwaiter]();
}
[createAwaiter](){
const promise = new Promise((resolve)=> {
if(this[sync]) this[sync]();
this[sync] = resolve;
});
this[queue] = this[queue].then(()=> promise);
}
[addQueue](resolve, reject){
this[queue] = this[queue].then(resolve, reject);
return this;
}
async sync(...args){
this[sync](...args);
const result = await this[queue];
this[createAwaiter]();
return result;
}
static get syncMethods(){ return syncMethods; }
}
const syncMethodList = (Base.prototype[syncMethods] && Base.prototype[syncMethods]()) || [];
for(const key of Reflect.ownKeys(Base.prototype)){
if(key === "constructor") continue;
if(key === syncMethods) continue;
if(syncMethodList.includes(key)) continue;
const descriptor = Object.getOwnPropertyDescriptor(Base.prototype, key);
const callback = descriptor && descriptor.value;
if(typeof(callback) !== "function") continue;
descriptor.value = function(){
return this[addQueue](callback);
};
Object.defineProperty(Base.prototype, key, descriptor);
}
return Awaiter;
});
export default Awaiter
import Awaiter from "./Awaiter";
// 各メソッドの定義方法
const Human = Awaiter(class Human{
async sayHello() {
await sleep(1000);
console.log('hello');
}
async sayBye() {
await sleep(1000);
console.log('bye');
}
});
const Gao = Awaiter(class Gao extends Human{
async sayAge(){
await sleep(1000);
console.log('18');
}
});
// 使い方
(async ()=>{
console.log('start');
await new Gao()
.sayHello()
.sayAge()
.sayBye()
.sync();
console.log('done');
})().catch(err=> {
console.error((err && err.stack) || err);
});
function sleep(ms) {
return new Promise((resolve)=> {
setTimeout(()=> {
resolve();
}, ms)
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment