Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Generators Talk

Alex Perry
February 04, 2016

Generators Talk

Talk at Mancjs about ES6 Generators

Alex Perry

February 04, 2016
Tweet

Other Decks in Programming

Transcript

  1. What are generators? •Generators introduce functions that can be paused

    •Currently, functions run until return or until completion
  2. Using Generators • Invoking a generator gives us an object

    that we can call ‘next’ on. function *sayHiAndBye() { yield 'hi'; yield 'bye'; } var myGenerator = sayHiAndBye(); myGenerator.next(); //{value: 'hi', done: 'false'} myGenerator.next(); //{value: 'bye', done: 'false'} myGenerator.next() // {value:'undefined', done: 'true'}
  3. Communicating with generators • Using next() you can pass values

    into generators function *sayFullName() { var firstName = yield 'first name'; var secondName = yield 'second name'; console.log(firstName + secondName); } var myGenerator = sayHiAndBye(); myGenerator.next(); //{value: 'first name', done: 'false'} myGenerator.next('alex '); //{value: 'second name', done: 'false'} myGenerator.next('perry') // {value:'undefined', done: 'true'}
  4. Generators and async function getFirstName() { setTimeout(function(){ gen.next('alex') }, 1000);

    } function getSecondName() { setTimeout(function(){ gen.next('perry') }, 1000); } function *sayHello() { var a = yield getFirstName(); var b = yield getSecondName(); console.log(a, b); //alex perry } var gen = sayHello(); gen.next(); 1. Next is called on the generator 2. getFirstName() returns undefined but next() is not called until the asynchronous activity has finished. 3. var is then defined as alex 4. getSecondName() is called and the function is again paused until next() is called 5. ‘alex perry’ is logged to the console
  5. Callbacks fs.readFile('directory/file-to-read', function(err, file){ if (error){ //handle error } else

    { //do something with the file fs.mkdir('directory/new-directory', function(err, file){ if (error) { //handle error } else { //new directory has been made fs.writeFile('directory/new-directory/message.txt', function(err, file){ if(error) { //handle error } else { //File successfully created } }); } }); } });
  6. Promises • An object that represents a future value using

    the ‘then’ method. fs.readFileAsync('directory/file-to-read') .then(function(fileData){ return fs.mkdirAsync('directory/new-directory'); }) .then(function(){ return fs.writeFileAsync('directory/new-directory/ message.txt'); }) • Then methods can be chained. Much more readable code
  7. Moonstick - Confirmation Page return data.booking(req).then(function (confirmationResult) { confirmation =

    confirmationResult; if (!req.moonstick.hotelID) { req.moonstick.hotelID = confirmation.HotelId; } return data.hotelDetails(req).then(function (hotel) { //Does somethings with 'hotel' }); });
  8. Confirmation page with generators return Promise.coroutine(function*(){ var confirmation = yield

    data.booking(req); if (!req.moonstick.hotelID) { req.moonstick.hotelID = confirmation.HotelId; } var hotelDetails = yield data.hotelDetails(req); return {hotelDetails: hotelDetails, confirmation: confirmation}; })().then((dataReturnedFromGenerator) => { //does some things with dataReturnedFromGenerator });
  9. New room availability return Promise.props({ rates: (someCondition) ? undefined :

    data.rates(req) .then(utils.findCheapestDouble) .then(function (ratesData) { return groupRates(ratesData, req, config, viewModel); }), hotelDetails: (someCondition) ? data.hotelDetails(req) : undefined }) .bind(this) .then(function createViewModel(apiData) { //do some cool stuff with the data });
  10. Room availability generators return Promise.coroutine(function* () { var rates =

    (someCondition) ? undefined : yield data.rates(req); var ratesDataWithCheapestDouble = utils.findCheapestDouble(rates); var groupedRatesData = groupRates(ratesDataWithCheapestDouble, req, config, viewModel); var hotelDetails = (someCondition) ? yield data.hotelDetails(req) : undefined; return { rates: groupedRatesData, hotelDetails: hotelDetails }; })().then((apiData) => { //do some cool stuff with the data });
  11. Before return data.hotelDetails(req).then(function (hotelDetails) { return data.search(hotelDetails.friendly_name).then(function (searchResults) { if

    (searchResults.results.length === 1) { urlObj.addModification('del-ne'); return urlObj; } if (searchResults.results.length > 1) { urlObj.addModification('del-hotels'); return urlObj; } return data.search(hotelDetails.location.city).then(function (citySearchResults) { if (citySearchResults.meta.keyword) { urlObj.addModification('del-kw'); } return urlObj; }); }); });
  12. Refactor return Promise.coroutine(function* () { const hotelDetails = yield data.hotelDetails(req);

    const searchResults = yield data.search(hotelDetails.friendly_name); if (searchResults.results.length === 1) { urlObj.addModification('del-ne'); } if (searchResults.results.length > 1) { urlObj.addModification('del-hotels'); } const citySearchResults = yield data.search(hotelDetails.location.city); if (citySearchResults.meta.keyword) { urlObj.addModification('del-kw'); } return urlObj; })();