{"id":96477,"date":"2017-06-28T07:00:00","date_gmt":"2017-06-28T21:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/?p=96477"},"modified":"2019-03-13T01:13:25","modified_gmt":"2019-03-13T08:13:25","slug":"20170628-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20170628-00\/?p=96477","title":{"rendered":"Extracting pages from a PDF document and saving them as separate image files, JavaScript edition with async"},"content":{"rendered":"<p><!-- backref: Extracting pages from a PDF document and saving them as separate image files, JavaScript edition with Promises -->Last time<\/a>, we converted the JavaScript version of the <a HREF=\"https:\/\/github.com\/Microsoft\/Windows-universal-samples\/tree\/v1.0.11\/Samples\/PdfDocument\">PDF Document<\/a> sample program so that it saved the pages to disk as image files. The asynchonous behavior was expressed via Promises. Today we&#8217;ll use the <code>async<\/code> and <code>await<\/code> keywords which didn&#8217;t make ECMAScript 7, but may make it into ECMAScript 8. Support for it <a HREF=\"https:\/\/blogs.windows.com\/msedgedev\/2015\/09\/30\/asynchronous-code-gets-easier-with-es2016-async-function-support-in-chakra-and-microsoft-edge\/\">arrived in Microsoft Edge as an experimental feature back in 2015<\/a>. <\/p>\n<pre>\n<font COLOR=\"blue\">async<\/font> function viewPage() {\n  WinJS.log &amp;&amp; WinJS.log(\"\", \"sample\", \"status\");\n\n  var pageNumber = parseInt(pageNumberBox.value, 10);\n  if (isNaN(pageNumber) || (pageNumber &lt; 1) ||\n    (pageNumber &gt; pdfDocument.pageCount)) {\n    WinJS.log &amp;&amp; WinJS.log(\"Invalid page number.\", \"sample\", \"error\");\n    return;\n  }\n\n  output.src = \"\";\n  progressControl.style.display = \"block\";\n\n  \/\/ Convert from 1-based page number to 0-based page index.\n  var pageIndex = pageNumber - 1;\n\n  var page = pdfDocument.getPage(pageIndex);\n\n  var picker = new Windows.Storage.Pickers.FileSavePicker();\n  picker.fileTypeChoices[\"PNG image2\"] = [\".png\"];\n  <font COLOR=\"blue\">var outfile = await picker.pickSaveFileAsync();<\/font>\n  if (outfile) {\n    <font COLOR=\"blue\">var transaction = await outfile.openTransactedWriteAsync();<\/font>\n    var options = new PdfPageRenderOptions();\n    options.destinationHeight = page.size.height * 2;\n    options.destinationWidth = page.size.width * 2;\n    <font COLOR=\"blue\">await page.renderToStreamAsync(transaction.stream, options);<\/font>\n    transaction.close();\n  }\n  page.close();\n  progressControl.style.display = \"none\";\n}\n<\/pre>\n<p>The <code>async<\/code> and <code>await<\/code> keywords are analogous to their C# counterparts. Declaring a function as <code>async<\/code> causes it to return a Promise whose result is the nominal type of the function. Inside an <code>async<\/code> function, you can use the <code>await<\/code> keyword to cause the continuation to be connected to the resolution of the Promise you are awaiting. <\/p>\n<p>There&#8217;s not much interesting to discuss here; it&#8217;s a straightforward translation of the C# sample. Note that JavaScript doesn&#8217;t have a <code>using<\/code> keyword, so we have to <code>close()<\/code> the closable objects manually. <\/p>\n<p>Next time, we&#8217;ll move on to C++\/CX. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Diving into an upcoming feature of ES8.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-96477","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Diving into an upcoming feature of ES8.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/96477","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=96477"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/96477\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=96477"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=96477"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=96477"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}