{"id":688,"date":"2020-04-07T10:00:23","date_gmt":"2020-04-07T09:00:23","guid":{"rendered":"https:\/\/marketaylor.synology.me\/?p=688"},"modified":"2020-04-01T17:47:31","modified_gmt":"2020-04-01T16:47:31","slug":"ibm-mq-node-js-promises","status":"publish","type":"post","link":"https:\/\/marketaylor.synology.me\/?p=688","title":{"rendered":"Promises from MQ and Node.js"},"content":{"rendered":"\n<p>In some earlier posts, <a rel=\"noreferrer noopener\" aria-label=\"here  (opens in a new tab)\" href=\"https:\/\/marketaylor.synology.me\/?p=513\" target=\"_blank\">here <\/a>and <a href=\"https:\/\/marketaylor.synology.me\/?p=505\">here<\/a>,  I wrote about how you can use Node.js to write MQ programs. In this post, I&#8217;ll show how a feature of the language, <strong>Promises<\/strong>, makes it easier to write those MQ programs.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p>Node.js programs are built from asynchronous blocks or functions. Many operations are done by initiating some work and then defining a (callback) function to be invoked once the work has completed in the background. The MQI layer is no different. Take a look at the<a rel=\"noreferrer noopener\" aria-label=\" amqsput sample  (opens in a new tab)\" href=\"https:\/\/github.com\/ibm-messaging\/mq-mqi-nodejs\/blob\/master\/samples\/amqsput.js\" target=\"_blank\"> amqsput sample <\/a>program for an example of how the callbacks get executed.<\/p>\n\n\n\n<p>This can be a very powerful approach, but it can also lead to very convoluted code. In fact, it&#8217;s often been called &#8220;<a rel=\"noreferrer noopener\" aria-label=\"callback hell (opens in a new tab)\" href=\"http:\/\/callbackhell.com\/\" target=\"_blank\">callback hell<\/a>&#8220;. It is easy to end up with multiple layers of nested operations, and a string of closing braces (some with semi-colons). In the <strong>amqsput <\/strong>sample, I tried not to get too deep into the nesting; the <code>Put<\/code> is in a separate top-level function called <em>putMessage<\/em>. But it can still be difficult to see the real structure and flow of the program.<\/p>\n\n\n\n<p>Especially when the flow needs to be inherently synchronous as parts of the MQ programming model are. You cannot call <strong>MQPUT <\/strong>until you have done an <strong>MQOPEN<\/strong>. And you cannot call <strong>MQOPEN <\/strong>until you have done an <strong>MQCONN<\/strong>.<\/p>\n\n\n\n<p>Promises are a mechanism that can make it much easier to code this kind of serial operation. I&#8217;m not going to write huge amounts of detail about how Promises work or a formal description of the interfaces. One good write-up is in<a rel=\"noreferrer noopener\" aria-label=\" this article (opens in a new tab)\" href=\"https:\/\/developer.ibm.com\/technologies\/node-js\/articles\/promises-in-nodejs-an-alternative-to-callbacks\/\" target=\"_blank\"> this article<\/a>. For our purposes, we just need to know there are two pieces of syntax to help &#8211;<em> .then()<\/em>and <em>.catch()<\/em>. Those names should already give an indication of what they try to achieve.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Promises and MQ<\/h3>\n\n\n\n<p>In a recent update to the <a rel=\"noreferrer noopener\" aria-label=\"MQI library for Node.js (opens in a new tab)\" href=\"https:\/\/github.com\/ibm-messaging\/mq-mqi-nodejs\" target=\"_blank\">MQI library for Node.js<\/a>, I added some Promise-based functions for the most commonly-used verbs where pseudo-synchrony could be useful.  <\/p>\n\n\n\n<p>The new forms of the verbs all have the <em>Promise <\/em>suffix, to distinguish them from the truly-synchronous verb variants and the (default) async versions. So to open a queue, you now have the option of calling any one of <code>Open<\/code>, <code>OpenSync<\/code>, or <code>OpenPromise<\/code> depending on which style of program you want. For example, in some of the sample programs I may call an <code>xxxxSync<\/code> function even though that is not recommended in production applications simply because it makes it easier to concentrate on the aspect of the sample that I was trying to demonstrate.<\/p>\n\n\n\n<p>The Promise-based flow can now look more like this pseudo-code.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">ConnxPromise()\n.then(return OpenPromise())\n.then(return PutPromise())\n.then(return ClosePromise())\n.then(return DiscPromise())\n.catch(err)<\/pre>\n\n\n\n<p>That looks a lot cleaner, even if the actual function is identical to other programs.<\/p>\n\n\n\n<p>Most of the asynchronous MQI verbs in this implementation return a single value to demonstrate success (the <em>hConn <\/em>for example after a successful connection), as well as an error indicator. Those values are available to be passed down the chain. <\/p>\n\n\n\n<p>For a complete working example of Promises, see the <a rel=\"noreferrer noopener\" aria-label=\"amqsputp  (opens in a new tab)\" href=\"https:\/\/github.com\/ibm-messaging\/mq-mqi-nodejs\/blob\/master\/samples\/amqsputp.js\" target=\"_blank\">amqsputp <\/a>sample program.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Which verbs<\/h3>\n\n\n\n<p>I created Promise-based functions for<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Conn, Connx, Disc<\/li><li>Open, Close<\/li><li>Put, Put1<\/li><li>Sub<\/li><\/ul>\n\n\n\n<p>You may notice that there&#8217;s not a Get in that list, which is deliberate. The behaviour of Get is inherently asynchronous and driving callbacks multiple times in this implementation, more like the <code>MQCB\/CallBack<\/code> or <code>onMessage<\/code> models in other languages. Although there is a <code>GetSync<\/code> verb, it is really <em>really <\/em><strong>really <\/strong>not recommended that you use it in production applications because it blocks everything else going on inside the Node.js environment while waiting for the message to arrive on a queue. While it might be possible to write a single-shot message receiver with a Promise wrapping the Get function, I thought that there could be too much variation in what people wanted to do for there to be a good prescriptive GetPromise method.<\/p>\n\n\n\n<p>The slightly-odd verb in this set is Sub. In the callback version, Sub needs to pass back two values &#8211; object handles for the subscription and for the destination queue. These are given as separate parameters to the callback function. In the Promise format, only one parameter can be passed down and so those two values are built into a single object containing the <em>hObj <\/em>and <em>hSub <\/em>elements. It&#8217;s the same function but spelled slightly differently.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Summary<\/h3>\n\n\n\n<p> Using Promises can help to simplify your Node.js application programs, making them easier to write and easier to maintain. I hope you find these Promises useful.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In some earlier posts, here and here, I wrote about how you can use Node.js to write MQ programs. In this post, I&#8217;ll show how a feature of the language, Promises, makes it easier to write those MQ programs.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[5],"tags":[35,20,63],"class_list":["post-688","post","type-post","status-publish","format-standard","hentry","category-mq","tag-ibmmq","tag-mqseries","tag-nodejs"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Promises from MQ and Node.js - Mark Taylor&#039;s Blog<\/title>\n<meta name=\"description\" content=\"Writing Node.js programs for IBM MQ becomes much easier when you can use Promises to deal with the asynchronous operatoins.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/marketaylor.synology.me\/?p=688\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Promises from MQ and Node.js - Mark Taylor&#039;s Blog\" \/>\n<meta property=\"og:description\" content=\"Writing Node.js programs for IBM MQ becomes much easier when you can use Promises to deal with the asynchronous operatoins.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/marketaylor.synology.me\/?p=688\" \/>\n<meta property=\"og:site_name\" content=\"Mark Taylor&#039;s Blog\" \/>\n<meta property=\"article:published_time\" content=\"2020-04-07T09:00:23+00:00\" \/>\n<meta name=\"author\" content=\"Mark\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@marketaylor\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Mark\" \/>\n\t<meta name=\"twitter:label2\" content=\"Estimated 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\":\"Article\",\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=688#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=688\"},\"author\":{\"name\":\"Mark\",\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/#\\\/schema\\\/person\\\/2d6f4113ff54187023e20c20186bbb3c\"},\"headline\":\"Promises from MQ and Node.js\",\"datePublished\":\"2020-04-07T09:00:23+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=688\"},\"wordCount\":743,\"commentCount\":0,\"keywords\":[\"ibmmq\",\"mqseries\",\"nodejs\"],\"articleSection\":[\"IBM MQ\"],\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/marketaylor.synology.me\\\/?p=688#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=688\",\"url\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=688\",\"name\":\"Promises from MQ and Node.js - Mark Taylor&#039;s Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/#website\"},\"datePublished\":\"2020-04-07T09:00:23+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/#\\\/schema\\\/person\\\/2d6f4113ff54187023e20c20186bbb3c\"},\"description\":\"Writing Node.js programs for IBM MQ becomes much easier when you can use Promises to deal with the asynchronous operatoins.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=688#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/marketaylor.synology.me\\\/?p=688\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=688#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/marketaylor.synology.me\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Promises from MQ and Node.js\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/#website\",\"url\":\"https:\\\/\\\/marketaylor.synology.me\\\/\",\"name\":\"Mark Taylor&#039;s Blog\",\"description\":\"Messaging, Music and Moving Around\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/marketaylor.synology.me\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-GB\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/#\\\/schema\\\/person\\\/2d6f4113ff54187023e20c20186bbb3c\",\"name\":\"Mark\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/9a5ae091c43730194cba7cabb5d65c1dc3f48d05caaddec6ff2319a1ce66376f?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/9a5ae091c43730194cba7cabb5d65c1dc3f48d05caaddec6ff2319a1ce66376f?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/9a5ae091c43730194cba7cabb5d65c1dc3f48d05caaddec6ff2319a1ce66376f?s=96&d=mm&r=g\",\"caption\":\"Mark\"},\"sameAs\":[\"https:\\\/\\\/x.com\\\/marketaylor\"],\"url\":\"https:\\\/\\\/marketaylor.synology.me\\\/?author=1\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Promises from MQ and Node.js - Mark Taylor&#039;s Blog","description":"Writing Node.js programs for IBM MQ becomes much easier when you can use Promises to deal with the asynchronous operatoins.","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:\/\/marketaylor.synology.me\/?p=688","og_locale":"en_GB","og_type":"article","og_title":"Promises from MQ and Node.js - Mark Taylor&#039;s Blog","og_description":"Writing Node.js programs for IBM MQ becomes much easier when you can use Promises to deal with the asynchronous operatoins.","og_url":"https:\/\/marketaylor.synology.me\/?p=688","og_site_name":"Mark Taylor&#039;s Blog","article_published_time":"2020-04-07T09:00:23+00:00","author":"Mark","twitter_card":"summary_large_image","twitter_creator":"@marketaylor","twitter_misc":{"Written by":"Mark","Estimated reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/marketaylor.synology.me\/?p=688#article","isPartOf":{"@id":"https:\/\/marketaylor.synology.me\/?p=688"},"author":{"name":"Mark","@id":"https:\/\/marketaylor.synology.me\/#\/schema\/person\/2d6f4113ff54187023e20c20186bbb3c"},"headline":"Promises from MQ and Node.js","datePublished":"2020-04-07T09:00:23+00:00","mainEntityOfPage":{"@id":"https:\/\/marketaylor.synology.me\/?p=688"},"wordCount":743,"commentCount":0,"keywords":["ibmmq","mqseries","nodejs"],"articleSection":["IBM MQ"],"inLanguage":"en-GB","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/marketaylor.synology.me\/?p=688#respond"]}]},{"@type":"WebPage","@id":"https:\/\/marketaylor.synology.me\/?p=688","url":"https:\/\/marketaylor.synology.me\/?p=688","name":"Promises from MQ and Node.js - Mark Taylor&#039;s Blog","isPartOf":{"@id":"https:\/\/marketaylor.synology.me\/#website"},"datePublished":"2020-04-07T09:00:23+00:00","author":{"@id":"https:\/\/marketaylor.synology.me\/#\/schema\/person\/2d6f4113ff54187023e20c20186bbb3c"},"description":"Writing Node.js programs for IBM MQ becomes much easier when you can use Promises to deal with the asynchronous operatoins.","breadcrumb":{"@id":"https:\/\/marketaylor.synology.me\/?p=688#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/marketaylor.synology.me\/?p=688"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/marketaylor.synology.me\/?p=688#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/marketaylor.synology.me\/"},{"@type":"ListItem","position":2,"name":"Promises from MQ and Node.js"}]},{"@type":"WebSite","@id":"https:\/\/marketaylor.synology.me\/#website","url":"https:\/\/marketaylor.synology.me\/","name":"Mark Taylor&#039;s Blog","description":"Messaging, Music and Moving Around","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/marketaylor.synology.me\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-GB"},{"@type":"Person","@id":"https:\/\/marketaylor.synology.me\/#\/schema\/person\/2d6f4113ff54187023e20c20186bbb3c","name":"Mark","image":{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/secure.gravatar.com\/avatar\/9a5ae091c43730194cba7cabb5d65c1dc3f48d05caaddec6ff2319a1ce66376f?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/9a5ae091c43730194cba7cabb5d65c1dc3f48d05caaddec6ff2319a1ce66376f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/9a5ae091c43730194cba7cabb5d65c1dc3f48d05caaddec6ff2319a1ce66376f?s=96&d=mm&r=g","caption":"Mark"},"sameAs":["https:\/\/x.com\/marketaylor"],"url":"https:\/\/marketaylor.synology.me\/?author=1"}]}},"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/marketaylor.synology.me\/index.php?rest_route=\/wp\/v2\/posts\/688","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/marketaylor.synology.me\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/marketaylor.synology.me\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/marketaylor.synology.me\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/marketaylor.synology.me\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=688"}],"version-history":[{"count":6,"href":"https:\/\/marketaylor.synology.me\/index.php?rest_route=\/wp\/v2\/posts\/688\/revisions"}],"predecessor-version":[{"id":694,"href":"https:\/\/marketaylor.synology.me\/index.php?rest_route=\/wp\/v2\/posts\/688\/revisions\/694"}],"wp:attachment":[{"href":"https:\/\/marketaylor.synology.me\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=688"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/marketaylor.synology.me\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=688"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/marketaylor.synology.me\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=688"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}