Commit 5ffd96e4 authored by David Votrubec's avatar David Votrubec

Added spawn function

parent ad9e5564
"use strict";
/**
* The runner function repeatedly calls the supplied generator function
* until all yields are exhausted.
*
* IT DOES NOT WORK WITH PROMISES
* because if continuable.value is a promise object, it can not be called as function
*/
export default function run (/*iterator fn*/ genFn) {
var gen = genFn(); // [1]
module.exports = function run(/*iterator fn*/ genFn) {
var iterator = genFn(); // [1]
next(); // [2]
function next (er, value) { // [3]
if (er) return gen.throw(er);
var continuable = gen.next(value);
function next (err, value) { // [3]
if (err) {
return iterator.throw(err);
}
var continuable = iterator.next(value);
if (continuable.done) return; // [4]
var cbFn = continuable.value; // [5]
cbFn(next);
var callbackFn = continuable.value; // [5]
callbackFn(next);
}
}
\ No newline at end of file
};
\ No newline at end of file
"use strict";
/**
* Create a `spawn` function to deal with promises
* Inspired by https://gist.github.com/dtothefp/a0a6a5c2e3dae8bc0d0f
*/
module.exports = function spawn(generatorFn) {
const iterator = generatorFn(); //instantiate the generator and return the iterator object
// create helper function which will call itself repeatedly
function _co(method, arg) {
let result;
try {
// retrieve the promise if `arg` is undefined (eg: returned by the http request)
// if `arg` is defined it will be the data from the promise
// and will be "injected" into `yield` and caught in a variable
result = iterator[method](arg); //method is either 'next' or 'throw'
} catch(err) {
return Promise.reject(err);
}
if (result.done) {
if (method === 'throw') {
return arg;
} else {
return result.value;
}
} else {
// Using the static Promise.resolve() method
// it will convert the result.value into a Promise object
// making it thenable.
// If there was an exception it will rethrown via _co('throw', err)
return Promise.resolve(result.value)
.then((val) => {
return _co('next', val);
}, (err) => {
return _co('throw', err);
});
}
}
// start the process by calling `.next` on the iterator instance
return _co('next');
};
\ No newline at end of file
import run from '03-run-function';
function loadArticle(articleId) {
const promise = new Promise(function(resolve, reject) {
setTimeout(function() {
console.log("successfully resolving articleId", articleId);
resolve();
}, 1000);
setTimeout(function() {
console.log("rejecting the promise articleId", articleId);
reject();
}, 2000);
});
return promise;
}
run(function*(){
const articleId = '1234a';
try {
const article = yield loadArticle(articleId);
// When article is loaded, load comments
//const comments = yield loadComments(articleId);
// When comments are loaded, load article's author
//const author = yield loadAuthor(article.authorId);
// in real life you would probably run all 3 request in parallel
// but you get the idea <img draggable="false" class="emoji" alt="🙂" src="https://s.w.org/images/core/emoji/72x72/1f642.png">
}
catch (err) {
console.log('error loading', err);
alert('Error loading article');
}
});
\ No newline at end of file
"use strict";
var run = require('./03-run-function');
var spawn = require('./04-spawn-function');
spawn(function*(){
const articleId = '1234abcd';
try {
const article = yield loadArticle(articleId);
// When article is loaded, load comments
const comments = yield loadComments(articleId);
// When comments are loaded, load article's author
const author = yield loadAuthor(article.authorId);
// in real life you would probably run all 3 request in parallel
}
catch (err) {
console.log('error loading', err);
alert('Error loading article');
}
});
// helper function
function getTimeoutPromise(timeout, resultValue, shouldReject) {
const promise = new Promise(function(resolve, reject) {
setTimeout(function() {
if (shouldReject) {
reject();
}
else {
resolve(resultValue);
}
}, timeout);
});
return promise;
}
function loadArticle(articleId) {
const promise = getTimeoutPromise(2000, {authorId: articleId + '_author'});
promise.then((data) => {
console.log("successfully resolving articleId", articleId, data);
});
return promise;
}
function loadComments(articleId) {
const promise = getTimeoutPromise(2000, {});
promise.then((data) => {
console.log("successfully resolving comments for articleId", articleId, data);
});
return promise;
}
function loadAuthor(articleId) {
const promise = getTimeoutPromise(2000);
promise.then(() => {
console.log("successfully resolving author of articleId", articleId);
resolve();
});
return promise;
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment