-
-
Save kumkanillam/d21aa8f8c323233c4dd6b95fdaa98440 to your computer and use it in GitHub Desktop.
New Twiddle
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Ember from 'ember'; | |
import { task, timeout } from 'ember-concurrency'; | |
export default Ember.Controller.extend({ | |
doDestructiveThing: task(function * () { | |
yield request('confirmation', { | |
message: "Are you sure?" | |
}); | |
let color = yield request('colorConfirmation', { | |
message: "What's your favorite color?", | |
colors: ["red", "green", "blue", "yellow"] | |
}); | |
return `You picked ${color}? That's too bad.`; | |
}).drop(), | |
}); | |
// TODO: add this as an import | |
const YIELDABLE = "__ec_yieldable__"; | |
// NOTE: everything below here is stuff library/addon authors | |
// would write. The whole point of the yieldables API is to | |
// let addon authors experiment with solutions to common | |
// UI problems involving async. | |
let INVOKE = "__invoke_symbol__"; | |
let locations = [ | |
'ember-glimmer/helpers/action', | |
'ember-routing-htmlbars/keywords/closure-action', | |
'ember-routing/keywords/closure-action' | |
]; | |
for (let i = 0; i < locations.length; i++) { | |
if (locations[i] in Ember.__loader.registry) { | |
INVOKE = Ember.__loader.require(locations[i])['INVOKE']; | |
break; | |
} | |
} | |
let Channel; | |
function request(name, payload) { | |
return { | |
[YIELDABLE](taskInstance, index) { | |
let obj = taskInstance.context; | |
payload.respond = response => { | |
taskInstance.proceed(index, "next", response); | |
}; | |
payload.cancel = () => { | |
taskInstance.proceed(index, "cancel", null); | |
}; | |
obj.set(name, payload); | |
return () => { | |
obj.set(name, null); | |
}; | |
}, | |
}; | |
} | |
Channel = Ember.Object.extend({ | |
init() { | |
this._super(); | |
this._takes = []; | |
this._puts = []; | |
this._refreshState(); | |
this.put = (...args) => this._put(...args); | |
}, | |
isActive: Ember.computed.or('isPutting', 'isTaking'), | |
isPutting: false, | |
isTaking: false, | |
[YIELDABLE](...args) { | |
// `yield channel` is the same as | |
// `yield channel.take()`; | |
return this.take()[YIELDABLE](...args); | |
}, | |
take() { | |
let takeAttempt = { | |
defer: Ember.RSVP.defer(), | |
active: true, | |
[YIELDABLE](taskInstance, resumeIndex) { | |
console.log("take yieldable"); | |
this.defer.promise.then(value => { | |
console.log(`resolve ${value}`); | |
taskInstance.proceed(resumeIndex, "next", value); | |
}); | |
return () => { | |
this.active = false; | |
}; | |
}, | |
}; | |
this._takes.push(takeAttempt); | |
this._scheduleFlush(); | |
return takeAttempt; | |
}, | |
_put(value) { | |
let putAttempt = { | |
value, | |
defer: Ember.RSVP.defer(), | |
active: true, | |
[YIELDABLE](taskInstance, resumeIndex) { | |
console.log("put yieldable"); | |
this.defer.promise.then(() => { | |
taskInstance.proceed(resumeIndex, "next", null); | |
}); | |
return () => { | |
this.active = false; | |
}; | |
}, | |
}; | |
this._puts.push(putAttempt); | |
this._scheduleFlush(); | |
return putAttempt; | |
}, | |
_scheduleFlush() { | |
Ember.run.schedule('actions', this, this._flush); | |
}, | |
_flush() { | |
let oldTakes = this._takes; | |
let puts = this._puts; | |
let newTakes = []; | |
for (let i = 0; i < oldTakes.length; ++i) { | |
let take = oldTakes[i]; | |
if (!take.active) { continue; } | |
while(puts.length) { | |
let put = puts.shift(); | |
if (!put.active) { continue; } | |
console.log("resolving take ", take, " with ", put.value); | |
take.defer.resolve(put.value); | |
put.defer.resolve(); | |
continue; | |
} | |
newTakes.push(take); | |
} | |
this._takes = newTakes; | |
this._refreshState(); | |
}, | |
_refreshState() { | |
this.setProperties({ | |
isTaking: this._takes.length > 0, | |
isPutting: this._putting.length > 0, | |
}); | |
}, | |
}); | |
function channel() { | |
return Ember.computed(function() { | |
return Channel.create(); | |
}); | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"version": "0.10.1", | |
"EmberENV": { | |
"FEATURES": {} | |
}, | |
"options": { | |
"use_pods": false, | |
"enable-testing": false | |
}, | |
"dependencies": { | |
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.js", | |
"ember": "2.6.0", | |
"ember-data": "2.6.1", | |
"ember-template-compiler": "2.6.0" | |
}, | |
"addons": { | |
"ember-concurrency": "pr-100" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment