Created
June 18, 2015 05:05
-
-
Save gihrig/1764bba1d0fc040cb9d4 to your computer and use it in GitHub Desktop.
Bhavr Delgtn Ex4
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
/* | |
YDKJS Async and Performance ch 4:Generators "Delegating Asynchrony" pg 163 | |
Delegating Asynchrony | |
Continuing the earlier multiple sequential Ajax requests | |
example, with yield-delegation: | |
This code is less than optimum as the first two requests are | |
called sequentially. They should be called concurrently. | |
See: gen-6-Concurrency.js | |
*/ | |
'use strict'; | |
/* | |
Generator runner utility | |
*/ | |
function run(gen) { | |
var args = [].slice.call(arguments, 1), it; | |
// initialize the generator in the current context | |
it = gen.apply(this, args); | |
// return a promise for the generator completing | |
return Promise.resolve() | |
.then(function handleNext(value) { | |
// run to the next yielded value | |
var next = it.next(value); | |
return (function handleResult(next) { | |
// generator has completed running? | |
if (next.done) { | |
return next.value; | |
} | |
// otherwise keep going | |
return Promise.resolve(next.value) | |
.then( | |
// resume the async loop on | |
// success, sending the resolved | |
// value back into the generator | |
handleNext, | |
// if `value` is a rejected | |
// promise, propagate error back | |
// into the generator for its own | |
// error handling | |
function handleErr(err) { | |
return Promise.resolve( | |
it.throw(err) | |
) | |
.then(handleResult); | |
} | |
); | |
})(next); | |
}); | |
} | |
// Promise returning Ajax call mock function | |
function request(url) { | |
return new Promise(function (resolve) { | |
setTimeout(function () { | |
var a = url.match(/v=(\d+)$/)[1] | |
console.log('requesting: ' + url + ' returned: ' + a); | |
resolve(a); | |
}, 1000); | |
}); | |
} | |
// Demonstration code - Serial execution | |
function *foo() { | |
var r2 = yield request('http://some.url/?v=2'); | |
var r3 = yield request('http://some.url/?v=3'); | |
return [r2, r3]; // return the result of both request calls | |
} | |
function *bar() { | |
var r1 = yield request('http://some.url/?v=1'); | |
var r3 = yield *foo(); // generator-delegation | |
console.log('*bar returned: ' + r1 + ',' + r3); | |
} | |
run(bar); | |
// requesting: http://some.url/?v=1 returned: 1 Notice that these | |
// requesting: http://some.url/?v=2 returned: 2 complete serially | |
// requesting: http://some.url/?v=3 returned: 3 | |
// *bar returned: 1,2,3 | |
// ========================================= | |
// Demonstration code - Concurrent execution | |
function *foo(param) { | |
// make first two requests concurrently | |
var p1 = request(param[0]); | |
var p2 = request(param[1]); | |
// wait until both promises resolve | |
var r1 = yield p1; | |
var r2 = yield p2; | |
return [r1, r2]; // return the result of both request calls | |
} | |
function *bar() { | |
var r1 = yield *foo(['http://some.url/?v=1', 'http://some.url.2/?v=2']); // generator-delegation | |
var r2 = yield request('http://some.url/?v=3'); | |
console.log('*bar returned: ' + r1 + ',' + r2); | |
} | |
run(bar); | |
// requesting: http://some.url/?v=1 returned: 1 Notice that these | |
// requesting: http://some.url/?v=2 returned: 2 complete concurrently | |
// requesting: http://some.url/?v=3 returned: 3 | |
// *bar returned: 1,2,3 | |
// ========================================= | |
/* | |
See gen-5-Generators+Promises.js for ES7 async function/await. | |
Removes dependency on run() utility. | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment