{"id":719,"date":"2013-06-04T20:20:55","date_gmt":"2013-06-04T18:20:55","guid":{"rendered":"http:\/\/blog.visisoft.de\/yalst\/?p=719"},"modified":"2015-05-28T23:09:32","modified_gmt":"2015-05-28T21:09:32","slug":"polling-ajax-with-when-js-and-jquery","status":"publish","type":"post","link":"https:\/\/www.yalst.de\/en\/polling-ajax-with-when-js-and-jquery\/","title":{"rendered":"Polling AJAX Using When.js with jQuery AJAX Promises"},"content":{"rendered":"<blockquote><p><strong>Abstract: Using <a title=\"when.js\" href=\"https:\/\/github.com\/cujojs\/when\" target=\"_blank\">when.js<\/a>&#8216; <code>poll<\/code> command together with <a title=\"jQuery's Ajax methods\" href=\"http:\/\/api.jquery.com\/category\/ajax\/\" target=\"_blank\">jQuery&#8217;s Ajax methods<\/a> <em>yalst<\/em> operator clients written in Javascript can define their data update loop with a minimal amount of code.<\/strong><\/p><\/blockquote>\n<h3>Contents<\/h3>\n<ol>\n<li><a href=\"#ajax_problem\">The Problem<\/a><\/li>\n<li><a href=\"#ajax_principle\">The Principle Of Promises<\/a><\/li>\n<li><a href=\"#ajax_polling\">When.js&#8217; Poll Method<\/a><\/li>\n<li><a href=\"#ajax_final_code\">The Monitor Code<\/a><\/li>\n<li><a href=\"#ajax_references\">References<\/a><\/li>\n<\/ol>\n<h3 id=\"ajax_problem\">The Problem<\/h3>\n<div>When implementing a web page like the <em>yalst<\/em> operator console which monitors frequently changing data the most reliable and most compatible method is still rapidly polling of <a href=\"https:\/\/netbeans.org\/kb\/docs\/php\/ajax-quickstart.html#overview\" target=\"_blank\">Ajax requests<\/a>. A number of websocket implementations use Ajax polling as a fallback in case the web socket connection can not be established[<a href=\"#ajax_ref1\">1<\/a>].<\/div>\n<div>Both the issuing of Ajax requests and periodically executing a worker function are common tasks when building web applications and are abstracted in many library implementations.<\/div>\n<h3 id=\"ajax_principle\">The Principle Of Promises<\/h3>\n<div>\n<p>A <a href=\"http:\/\/net.tutsplus.com\/tutorials\/javascript-ajax\/promise-based-validation\/\" target=\"_blank\">Promise-based<\/a> interface provides a nice way to decouple the asynchronous internals of the network operation from the application program flow.<\/p>\n<blockquote><p>A general description is that a <a href=\"http:\/\/wiki.commonjs.org\/wiki\/Promises\/A\" target=\"_blank\">promise<\/a> encapsulates the final result of an asynchronous operation. A promise may be in one of the three states, <code>\"pending\"<\/code>, <code>\"resolved\"<\/code>, and <code>\"rejected\"<\/code>. The promise itself accepts callbacks via its <code>then<\/code> method.[<a href=\"#ajax_ref2\">2<\/a>]<\/p><\/blockquote>\n<p>Which means that instead of specifying callback functions in the call of an asynchronous operation that operation simply returns a promise (so to speak a &#8220;promise&#8221; of its eventual result).<\/p>\n<\/div>\n<div>This diagram depicts the basic features:<br \/>\n<div id=\"attachment_748\" style=\"width: 748px\" class=\"wp-caption alignleft\"><img aria-describedby=\"caption-attachment-748\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-748\" src=\"https:\/\/www.yalst.de\/wp-content\/uploads\/2015\/04\/promise_definition.png\" alt=\"Time sequence of asynchronous I\/O using a promise object to wrap the results.\" width=\"738\" height=\"373\" \/><p id=\"caption-attachment-748\" class=\"wp-caption-text\">Time sequence of asynchronous I\/O using a promise object to wrap the results. The gray box groups an alternative line of execution. [<a href=\"#ajax_ref3\">3<\/a>].<\/p><\/div><\/div>\n<div>\n<p>The <em>advantage<\/em> is that it is easy to <em>compose<\/em> new promises from existing ones. Examples are<\/p>\n<ul>\n<li>The <em>combined<\/em> promise <code>all<\/code> which resolves not until all given promises resolve (e.g. loading a bunch of images before displaying the slide show).<\/li>\n<li>The <em>competitive<\/em> promise <code>any<\/code> which evaluates to the return value of the promise whichever one completes first (e.g. timing out an operation by combining it with a timeout promise)<\/li>\n<li>The <em>propagation\/forwarding<\/em> of promises by returning a new promise from a <code>then<\/code> callback. E.g. when polling Ajax in case the reason for an Ajax failure was a timeout condition the <code>onRejected()<\/code> handler could resolve a newly created promise with a default value an return that promise. Thus the poll control loop is not interrupted.<\/li>\n<\/ul>\n<p>Another advantage is that <em>sequential chains<\/em> of asynchronous logic actually appear sequential with promises rather than with the unwieldy nesting patterns of callback functions [<a href=\"#ajax_ref5\">5<\/a>].<\/p>\n<\/div>\n<h3>The Libraries<\/h3>\n<div>Usually the first candidate for a library implementation is always the well-established jQuery library. Fortunately it&#8217;s <a href=\"http:\/\/api.jquery.com\/jQuery.ajax\/\" target=\"_blank\">Ajax<\/a> objects already implement a promise interface, well done! However to repeatedly poll a worker promise neither jQuery nor <a href=\"http:\/\/underscorejs.org\/\" target=\"_blank\">underscore<\/a> <abbr>i.e.<\/abbr><a href=\"http:\/\/lodash.com\/docs\" target=\"_blank\">Low-Dash<\/a> provide suitable methods.<\/div>\n<div>\n<p>Browsing for other promise libraries the simple API of <a href=\"https:\/\/github.com\/cujojs\/when\" target=\"_blank\">When.js<\/a> [<a href=\"#ajax_ref4\">4<\/a>] stands out. It&#8217;s features include<\/p>\n<ul>\n<ul>\n<li>important combinators like <code>map<\/code>, <code>all<\/code>, <code>any<\/code>, <code>pipeline<\/code>, <code>sequence<\/code>, <code>parallel<\/code>,&#8230;<\/li>\n<li>convenient utility promises like <code>timeout<\/code>, <code>delay<\/code> and <code>poll<\/code><\/li>\n<li><a href=\"http:\/\/jsfiddle.net\/Semmel\/rttpv\/\" target=\"_blank\">coexisting with jQuery promises<\/a> and<\/li>\n<li>transforming other callback-based APIs into promise-based APIs, e.g. when loading an image:<\/li>\n<\/ul>\n<\/ul>\n<pre class=\"prettyprint\"><code class=\"language-javascript\">\r\nrequire(['when', 'when\/callbacks'], function(when, callbacks){\r\n\tvar img = $('<img alt=\"\" \/>');\r\n\tvar imagePromise = callbacks.call(img.on.bind(img, 'load', null, null));\r\n\timagePromise.then(console.log.bind(console, \"Loaded\"));\r\n\timg.get(0).src = \"put image url here\";\r\n});\r\n<\/code><\/pre>\n<\/div>\n<h3 id=\"ajax_polling\">When.js&#8217; Poll Method<\/h3>\n<div>\n<p>The <a href=\"https:\/\/github.com\/cujojs\/when\/blob\/master\/docs\/api.md#polling-with-promises\" target=\"_blank\">When.js <code>poll<\/code> method<\/a> will<\/p>\n<blockquote><p>&#8220;execute a <code>worker<\/code> task repeatedly at the specified interval <code>\u0394T<\/code>, until the <code>shouldFinish<\/code> condition function returns true. The <code>resultPromise<\/code> will be resolved with the most recent value returned from <code>worker<\/code>. If <code>worker<\/code> fails (throws an exception or returns a rejected promise) before <code>shouldFinish<\/code> condition returns true, the <code>resultPromise<\/code> will be rejected.&#8221; [<a href=\"#ajax_ref4\">4<\/a>]<\/p><\/blockquote>\n<p>which is an excellent choice for wrapping the jQuery Ajax worker function for our purpose.<\/p>\n<\/div>\n<div>However since there are two different promises involved now the program flow can get confusing. In order to clarify their dependence the next digram depicts all possible outcomes of this combination. Due to this article&#8217;s format the time axis is rotated pointing from top to bottom.<\/div>\n<div id=\"attachment_737\" style=\"width: 567px\" class=\"wp-caption alignleft\"><img aria-describedby=\"caption-attachment-737\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-737\" src=\"https:\/\/www.yalst.de\/wp-content\/uploads\/2015\/04\/whenjs_poll_with_jQuery_promises.png\" alt=\"Using when.js poll method with a worker function returning a jQuery promise\" width=\"557\" height=\"1819\" \/><p id=\"caption-attachment-737\" class=\"wp-caption-text\">Using when.js poll method with a worker function returning a jQuery promise. The gray boxes group alternative lines of execution. Please feel free to verify his behaviour in this <a href=\"http:\/\/jsfiddle.net\/Semmel\/jC8aE\/2\/\" target=\"_blank\">JsFiddle<\/a>.<\/p><\/div>\n<h3 id=\"ajax_final_code\">The Monitor Code<\/h3>\n<div>\n<p>As &#8220;promised&#8221; here is the final code which defines the monitoring loop in the <em>yalst<\/em> operator console.<\/p>\n<pre class=\"prettyprint\"><code>\r\nfunction ajaxWorker(){\r\n\treturn $.ajax(webServiceUrl, {dataType: 'json', timeout: 20000})\r\n\t\t.then(null, function(xhr, status, httpErrorDescription){\r\n\t\t\tif (status == \"timeout\"){\r\n\t\t\t\tvar dfd = new $.Deferred();\r\n\t\t\t\tdfd.resolve(PollResult.timeout);\r\n\t\t\t\treturn dfd.promise();\r\n\t\t\t}\r\n\t\t});\r\n}\r\nvar polling = poll(ajaxWorker, intervalTimeout, function(pollResult){ \r\n\treturn pollResult != PollResult.serverOverload; });\r\n<\/code><\/pre>\n<\/div>\n<h3 id=\"ajax_references\">References<\/h3>\n<div><span id=\"ajax_ref1\">[1]<\/span> see the section &#8220;Pushing and Polling&#8221; at <a href=\"http:\/\/blog.fogcreek.com\/the-trello-tech-stack\/\" target=\"_blank\">http:\/\/blog.fogcreek.com\/the-trello-tech-stack\/<\/a><\/div>\n<div><span id=\"ajax_ref2\">[2]<\/span> <a href=\"http:\/\/wiki.commonjs.org\/wiki\/Promises\/A\" target=\"_blank\">http:\/\/wiki.commonjs.org\/wiki\/Promises\/A<\/a><\/div>\n<div><span id=\"ajax_ref3\">[3]<\/span> idea for the diagram shamelessly taken from <a href=\"http:\/\/net.tutsplus.com\/tutorials\/javascript-ajax\/promise-based-validation\/\" target=\"_blank\">NetTuts+<\/a><\/div>\n<div><span id=\"ajax_ref4\">[4]<\/span> When.js documentation, <a href=\"https:\/\/github.com\/cujojs\/when\/blob\/master\/docs\/api.md\" target=\"_blank\">https:\/\/github.com\/cujojs\/when\/blob\/master\/docs\/api.md<\/a><\/div>\n<div><span id=\"ajax_ref5\">[5]<\/span> David Herman: &#8220;Effective Javascript&#8221; , 2012 by Addison-Wesley, <a href=\"http:\/\/effectivejs.com\" target=\"_blank\">http:\/\/effectivejs.com<\/a><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Repeatedly polling data via AJAX can be elegantly implemented using When.js&#8217; poll function with jQuery&#8217;s promise interface for AJAX.<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[67],"tags":[68,86,87],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v20.12 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Polling AJAX Using When.js with jQuery AJAX Promises - yalst - Live Support | Live Chat | Live Help | Help Desk<\/title>\n<meta name=\"description\" content=\"Repeatedly polling AJAX data can be elegantly implemented using When.js&#039; poll function with jQuery&#039;s promise interface for AJAX.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.yalst.de\/en\/polling-ajax-with-when-js-and-jquery\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Polling AJAX Using When.js with jQuery AJAX Promises - yalst - Live Support | Live Chat | Live Help | Help Desk\" \/>\n<meta property=\"og:description\" content=\"Repeatedly polling AJAX data can be elegantly implemented using When.js&#039; poll function with jQuery&#039;s promise interface for AJAX.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.yalst.de\/en\/polling-ajax-with-when-js-and-jquery\/\" \/>\n<meta property=\"og:site_name\" content=\"yalst - Live Support | Live Chat | Live Help | Help Desk\" \/>\n<meta property=\"article:published_time\" content=\"2013-06-04T18:20:55+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2015-05-28T21:09:32+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.yalst.de\/wp-content\/uploads\/2015\/04\/promise_definition.png\" \/>\n<meta name=\"author\" content=\"Matthias Seemann\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Matthias Seemann\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.yalst.de\/en\/polling-ajax-with-when-js-and-jquery\/\",\"url\":\"https:\/\/www.yalst.de\/en\/polling-ajax-with-when-js-and-jquery\/\",\"name\":\"Polling AJAX Using When.js with jQuery AJAX Promises - yalst - Live Support | Live Chat | Live Help | Help Desk\",\"isPartOf\":{\"@id\":\"https:\/\/www.yalst.de\/en\/#website\"},\"datePublished\":\"2013-06-04T18:20:55+00:00\",\"dateModified\":\"2015-05-28T21:09:32+00:00\",\"author\":{\"@id\":\"https:\/\/www.yalst.de\/en\/#\/schema\/person\/32edfd67d7dc13e809181afe316fcccb\"},\"description\":\"Repeatedly polling AJAX data can be elegantly implemented using When.js' poll function with jQuery's promise interface for AJAX.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.yalst.de\/en\/polling-ajax-with-when-js-and-jquery\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.yalst.de\/en\/polling-ajax-with-when-js-and-jquery\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.yalst.de\/en\/polling-ajax-with-when-js-and-jquery\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.yalst.de\/en\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Polling AJAX Using When.js with jQuery AJAX Promises\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.yalst.de\/en\/#website\",\"url\":\"https:\/\/www.yalst.de\/en\/\",\"name\":\"yalst - Live Support | Live Chat | Live Help | Help Desk\",\"description\":\"Ihr umfassender Live Support Chat\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.yalst.de\/en\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.yalst.de\/en\/#\/schema\/person\/32edfd67d7dc13e809181afe316fcccb\",\"name\":\"Matthias Seemann\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.yalst.de\/en\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/6d883a962ac315cf385799a15783f440?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/6d883a962ac315cf385799a15783f440?s=96&d=mm&r=g\",\"caption\":\"Matthias Seemann\"},\"description\":\"Entwickler und Mitglied der Gesch\u00e4ftsf\u00fchrung bei der Visisoft OHG\",\"url\":\"https:\/\/www.yalst.de\/en\/author\/seemannvisisoft-de\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Polling AJAX Using When.js with jQuery AJAX Promises - yalst - Live Support | Live Chat | Live Help | Help Desk","description":"Repeatedly polling AJAX data can be elegantly implemented using When.js' poll function with jQuery's promise interface for AJAX.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.yalst.de\/en\/polling-ajax-with-when-js-and-jquery\/","og_locale":"en_US","og_type":"article","og_title":"Polling AJAX Using When.js with jQuery AJAX Promises - yalst - Live Support | Live Chat | Live Help | Help Desk","og_description":"Repeatedly polling AJAX data can be elegantly implemented using When.js' poll function with jQuery's promise interface for AJAX.","og_url":"https:\/\/www.yalst.de\/en\/polling-ajax-with-when-js-and-jquery\/","og_site_name":"yalst - Live Support | Live Chat | Live Help | Help Desk","article_published_time":"2013-06-04T18:20:55+00:00","article_modified_time":"2015-05-28T21:09:32+00:00","og_image":[{"url":"https:\/\/www.yalst.de\/wp-content\/uploads\/2015\/04\/promise_definition.png"}],"author":"Matthias Seemann","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Matthias Seemann","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.yalst.de\/en\/polling-ajax-with-when-js-and-jquery\/","url":"https:\/\/www.yalst.de\/en\/polling-ajax-with-when-js-and-jquery\/","name":"Polling AJAX Using When.js with jQuery AJAX Promises - yalst - Live Support | Live Chat | Live Help | Help Desk","isPartOf":{"@id":"https:\/\/www.yalst.de\/en\/#website"},"datePublished":"2013-06-04T18:20:55+00:00","dateModified":"2015-05-28T21:09:32+00:00","author":{"@id":"https:\/\/www.yalst.de\/en\/#\/schema\/person\/32edfd67d7dc13e809181afe316fcccb"},"description":"Repeatedly polling AJAX data can be elegantly implemented using When.js' poll function with jQuery's promise interface for AJAX.","breadcrumb":{"@id":"https:\/\/www.yalst.de\/en\/polling-ajax-with-when-js-and-jquery\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.yalst.de\/en\/polling-ajax-with-when-js-and-jquery\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.yalst.de\/en\/polling-ajax-with-when-js-and-jquery\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.yalst.de\/en\/"},{"@type":"ListItem","position":2,"name":"Polling AJAX Using When.js with jQuery AJAX Promises"}]},{"@type":"WebSite","@id":"https:\/\/www.yalst.de\/en\/#website","url":"https:\/\/www.yalst.de\/en\/","name":"yalst - Live Support | Live Chat | Live Help | Help Desk","description":"Ihr umfassender Live Support Chat","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.yalst.de\/en\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.yalst.de\/en\/#\/schema\/person\/32edfd67d7dc13e809181afe316fcccb","name":"Matthias Seemann","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.yalst.de\/en\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/6d883a962ac315cf385799a15783f440?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/6d883a962ac315cf385799a15783f440?s=96&d=mm&r=g","caption":"Matthias Seemann"},"description":"Entwickler und Mitglied der Gesch\u00e4ftsf\u00fchrung bei der Visisoft OHG","url":"https:\/\/www.yalst.de\/en\/author\/seemannvisisoft-de\/"}]}},"_links":{"self":[{"href":"https:\/\/www.yalst.de\/en\/wp-json\/wp\/v2\/posts\/719"}],"collection":[{"href":"https:\/\/www.yalst.de\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.yalst.de\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.yalst.de\/en\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.yalst.de\/en\/wp-json\/wp\/v2\/comments?post=719"}],"version-history":[{"count":6,"href":"https:\/\/www.yalst.de\/en\/wp-json\/wp\/v2\/posts\/719\/revisions"}],"predecessor-version":[{"id":4221,"href":"https:\/\/www.yalst.de\/en\/wp-json\/wp\/v2\/posts\/719\/revisions\/4221"}],"wp:attachment":[{"href":"https:\/\/www.yalst.de\/en\/wp-json\/wp\/v2\/media?parent=719"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.yalst.de\/en\/wp-json\/wp\/v2\/categories?post=719"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.yalst.de\/en\/wp-json\/wp\/v2\/tags?post=719"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}