Created
November 9, 2015 10:34
-
-
Save TiddoLangerak/0a1b2dd43e8bdc239898 to your computer and use it in GitHub Desktop.
async generators
This file contains 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
//Simple, without $await | |
//In the simple variant $async/yield works like async/await. That is, yield "awaits" a promise, | |
//and an $async function still returns a promise | |
const init = $async(function*() { | |
const user = yield $http.get('/users/me'); | |
$scope.user = user; | |
const messages = yield messageService.getMessagesFor(user); | |
$scope.messages = messages; | |
}); | |
init() //See, it returns a promise | |
.then(() => console.log('done')); | |
//Complex, with $await | |
//In the complex variant $async returns a generator function. This allows for more flexibility, | |
//but requires a lot more boilerplate. | |
//Same example: | |
const init = $asyncGenerator(function*() { | |
const user = yield $await($http.get('/users/me')); | |
$scope.user = user; | |
const messages = yield $await(messageService.getMessagesFor(user)); | |
$scope.messages = messages; | |
}); | |
//Since it's a generator function we need to kickstart it first, as well as extract the value manually | |
init().next().value | |
.then(() => console.log("done")); | |
//likeley we'll abstract to above into something like this: | |
$async.run(init()) | |
.then(() => console.log("done")); | |
//The above example doesn't really seem any better, however it does allow us to do the following (which is awesome!): | |
const messageGenerator = $asyncGenerator(function*() { | |
let offset = 0; | |
const batchSize = 10; | |
while (true) { | |
//Yield $async causes the execution of the function to halt until the promise is ready | |
const messages = yield $async($http.get('messages', { offset, limit : batchSize })); | |
if (messages.length === 0) { | |
//No more messages! | |
return; | |
} | |
for (let message of messages) { | |
//Yield without $async works as a normal yield | |
yield message; | |
} | |
offset += batchSize; | |
} | |
}); | |
const fetchNextMessages = $async(function*(amount) { | |
//Since we can have an async generator we can easily implement rx-like behaviour, where we add each message as it comes in. | |
const messageStream = yield $stream(messageIterator).fetch(amount); | |
messageStream | |
.map((message) => processMessage(message)) | |
.forEach(message => $scope.messages.push(message)); | |
//But we can also still do batch processing as if it where synchronous code: | |
const messages = yield $await(messageStream); | |
doStuffWithAllMessages(messages); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment