{"id":626,"date":"2014-04-08T22:00:00","date_gmt":"2014-04-08T19:00:00","guid":{"rendered":"http:\/\/blog.iridi.com\/en\/2014\/04\/08\/javascript-self-adjusting-timers\/"},"modified":"2018-07-18T13:22:52","modified_gmt":"2018-07-18T10:22:52","slug":"javascript-self-adjusting-timers","status":"publish","type":"post","link":"https:\/\/blog.iridi.com\/en\/javascript-self-adjusting-timers\/","title":{"rendered":"JavaScript: Self-adjusting Timers"},"content":{"rendered":"<p><i>Ilya Markov<\/i><\/p>\n<p><i>Script programmer at iRidium mobile<\/i><\/p>\n<p><img class=\"aligncenter\" title=\"JavaScript: Self-adjusting Timers\" src=\"https:\/\/iridiummobile.net\/upload\/medialibrary\/238\/2380058ac315743066d02b06b97ce1cc.jpg\" alt=\"JavaScript: Self-adjusting Timers\" width=\"100%\" border=\"0\" \/><\/p>\n<p>The image to the post is a painting by Salvador Dali \u201cTime flows\u201d. The choice is not a chance one and essentially metaphorical.<\/p>\n<p>&nbsp;<\/p>\n<p>In JS programming time may flow in a way, different from what we suppose it to. JavaScript is single-threaded. So, functions take turns for a piece of CPU time, and the time they have to wait varies, depending on the load. This is what causes latency in timers that can be up to 2-3msec. And this latency tends to accumulate. It\u2019s crucially important, when controlling transient processes.<\/p>\n<p>Personally I came across an impossibility to create an accurate timer by standard means: setTimeout() \u0438 setInterval() a couple of months ago, when I was working at a small project. The latency came up to inacceptable 0.5 sec.<\/p>\n<p>James Edwards, a freelance web developer, specializing in JavaScript application development, suggests solving the task of accurate timing this way. The first thing to do to keep the timer accurate is to work out exactly how inaccurate it is, and subtract that difference from the next iteration. So, the following code was written:<\/p>\n<p><img class=\"herta\" src=\"http:\/\/www.iridiummobile.net\/new_include_areas\/img\/herta.png\" \/><\/p>\n<p class=\"MsoNoSpacing\"><span style=\"font-size: 10pt; color: black;\">var start = new Date().getTime(),<\/span><\/p>\n<p class=\"MsoNoSpacing\"><span style=\"font-size: 10pt; color: black;\">\u00a0\u00a0\u00a0 time = 0,<\/span><\/p>\n<p class=\"MsoNoSpacing\"><span style=\"font-size: 10pt; color: black;\">\u00a0\u00a0\u00a0 elapsed = &#8216;0.0&#8217;;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p class=\"MsoNoSpacing\"><span style=\"font-size: 10pt; color: black;\">function instance()<\/span><\/p>\n<p class=\"MsoNoSpacing\"><span style=\"font-size: 10pt; color: black;\">{<\/span><\/p>\n<p class=\"MsoNoSpacing\"><span style=\"font-size: 10pt; color: black;\">\u00a0\u00a0\u00a0 time += 100;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p class=\"MsoNoSpacing\"><span style=\"font-size: 10pt; color: black;\">\u00a0\u00a0\u00a0 elapsed = Math.floor(time \/ 100) \/ 10;<\/span><\/p>\n<p class=\"MsoNoSpacing\"><span style=\"font-size: 10pt; color: black;\">\u00a0\u00a0\u00a0 if(Math.round(elapsed) == elapsed) { elapsed += &#8216;.0&#8217;; }<\/span><\/p>\n<p>&nbsp;<\/p>\n<p class=\"MsoNoSpacing\"><span style=\"font-size: 10pt; color: black;\">\u00a0\u00a0\u00a0 var diff = (new Date().getTime() &#8211; start) &#8211; time;<\/span><\/p>\n<p class=\"MsoNoSpacing\"><span style=\"font-size: 10pt; color: black;\">\u00a0\u00a0\u00a0 IR.SetTimeout((100 &#8211; diff), instance);<\/span><\/p>\n<p class=\"MsoNoSpacing\"><span style=\"font-size: 10pt; color: black;\">}<\/span><\/p>\n<p>&nbsp;<\/p>\n<p class=\"MsoNoSpacing\"><span style=\"font-size: 10pt; color: black;\">IR.SetTimeout(100, instance,);<\/span><\/p>\n<p><img class=\"herta\" src=\"http:\/\/www.iridiummobile.net\/new_include_areas\/img\/herta.png\" \/><\/p>\n<p>It\u2019s a simple and good solution. The advantage is that it does not matter how inaccurate the timer is, as consequently the small latency of 3-4ms can be easily compensated. Whereas inaccuracy of a regular timer accumulates with each iteration and becomes noticeable.<\/p>\n<p>As I mentioned I came across a problem of inaccurate times when working at a small audio project. After going into theory of creating accurate times in JS, I wrote the following code on the basis of the one suggested by James Edwards.<\/p>\n<p><img class=\"herta\" src=\"http:\/\/www.iridiummobile.net\/new_include_areas\/img\/herta.png\" \/><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span style=\"color: gray;\">\/\/when pressing &#8220;play\/stop&#8221;, a timer function is activated<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span style=\"color: #222222;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span><span style=\"color: #4d7386;\">function<\/span> preciousTimer<span style=\"color: #222222;\"> (step) {<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span style=\"color: #222222;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span style=\"color: gray;\">\/\/like in examples above, we take DateStamp for evaluation<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span style=\"color: #222222;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span><span lang=\"EN-US\" style=\"color: #4d7386;\">var<\/span><span lang=\"EN-US\" style=\"color: #222222;\"> start = <\/span><span lang=\"EN-US\" style=\"color: #4d7386;\">new<\/span><span lang=\"EN-US\" style=\"color: #222222;\"> Date().getTime(),<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span lang=\"EN-US\" style=\"color: #222222;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span><span style=\"color: #222222;\">time = <\/span><span style=\"color: #2f98ff;\">0<\/span><span style=\"color: #222222;\">,<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span style=\"color: gray;\">\/*this variable was caused by the necessity<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span style=\"color: gray;\">to have an even number as many iterations<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span style=\"color: gray;\">as steps in the sequencer (the accuracy is still low)*\/<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span style=\"color: #222222;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 it = <\/span><span style=\"color: #2f98ff;\">0<\/span><span style=\"color: #222222;\">;<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span style=\"color: #222222;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span style=\"color: #222222;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span><span style=\"color: #4d7386;\">function<\/span> instance<span style=\"color: #222222;\"> () {<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span style=\"color: #222222;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span style=\"color: gray;\">\/\/calculate the ideal time <\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span style=\"color: #222222;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span><span lang=\"EN-US\" style=\"color: #222222;\">time += step;<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span lang=\"EN-US\" style=\"color: #222222;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span lang=\"EN-US\" style=\"color: gray;\">\/\/<\/span><span style=\"color: gray;\">calculate the difference<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span lang=\"EN-US\" style=\"color: #222222;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span><span lang=\"EN-US\" style=\"color: #4d7386;\">var<\/span><span lang=\"EN-US\" style=\"color: #222222;\"> diff = (<\/span><span lang=\"EN-US\" style=\"color: #4d7386;\">new<\/span><span lang=\"EN-US\" style=\"color: #222222;\"> Date().getTime()- start) &#8211; time;<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span lang=\"EN-US\" style=\"color: #222222;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span style=\"color: gray;\">\/\/act by the iterator value<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span style=\"color: #222222;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span><span style=\"color: #4d7386;\">if<\/span><span style=\"color: #222222;\"> (it == <\/span><span style=\"color: #2f98ff;\">4<\/span><span style=\"color: #222222;\">) {<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span style=\"color: #222222;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 it = <\/span><span style=\"color: #2f98ff;\">0<\/span><span style=\"color: #222222;\">;<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span style=\"color: gray;\">\/*a place of sequencer working with matrix,<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span style=\"color: gray;\">here we see the value of logic arrays<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span style=\"color: gray;\">for every passage. *\/<\/span><span style=\"color: #222222;\">\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span style=\"color: #222222;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span><span style=\"color: #4d7386;\">if<\/span><span style=\"color: #222222;\"> (m == <\/span><span style=\"color: #2f98ff;\">8<\/span><span style=\"color: #222222;\">) {<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span style=\"color: #222222;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span><span lang=\"EN-US\" style=\"color: #222222;\">m<\/span><span style=\"color: #222222;\"> = <\/span><span style=\"color: #2f98ff;\">0<\/span><span style=\"color: #222222;\">;<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span style=\"color: #222222;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span><span lang=\"EN-US\" style=\"color: #222222;\">};<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span lang=\"EN-US\" style=\"color: #222222;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span><span lang=\"EN-US\" style=\"color: #4d7386;\">for<\/span><span lang=\"EN-US\" style=\"color: #222222;\"> (<\/span><span lang=\"EN-US\" style=\"color: #4d7386;\">var<\/span><span lang=\"EN-US\" style=\"color: #222222;\"> i = <\/span><span lang=\"EN-US\" style=\"color: #2f98ff;\">0<\/span><span lang=\"EN-US\" style=\"color: #222222;\">; i &lt; <\/span><span lang=\"EN-US\" style=\"color: #2f98ff;\">4<\/span><span lang=\"EN-US\" style=\"color: #222222;\">; i++) {<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span lang=\"EN-US\" style=\"color: #222222;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span><span lang=\"EN-US\" style=\"color: #4d7386;\">if<\/span><span lang=\"EN-US\" style=\"color: #222222;\"> (noteArr[i][m]) {<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span lang=\"EN-US\" style=\"color: #222222;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 sound[i].play();<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span lang=\"EN-US\" style=\"color: #222222;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 };<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span lang=\"EN-US\" style=\"color: #222222;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 };<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span lang=\"EN-US\" style=\"color: #222222;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 m++;<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span lang=\"EN-US\" style=\"color: #222222;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 };<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span lang=\"EN-US\" style=\"color: #222222;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 it++;<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span lang=\"EN-US\" style=\"color: #222222;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span style=\"color: gray;\">\/\/if \u201cpause\u201d is pressed during an iteration,<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span style=\"color: gray;\">\/\/leave the end of the recursive chain<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span style=\"color: #222222;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span><span style=\"color: #4d7386;\">if<\/span><span style=\"color: #222222;\"> (pause) { <\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span style=\"color: #222222;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span><span style=\"color: #4d7386;\">return<\/span><span style=\"color: #222222;\">; <\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span style=\"color: #222222;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 };<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span style=\"color: #222222;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span style=\"color: gray;\">\/\/call the next iteration, considering the latency<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span style=\"color: #222222;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span><span lang=\"EN-US\" style=\"color: #222222;\">IR.SetTimeout((step &#8211; diff), instance);<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span lang=\"EN-US\" style=\"color: #222222;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span><span style=\"color: #222222;\">};<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span style=\"color: #222222;\">\u00a0<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span style=\"color: gray;\">\/\/It\u2019s the first call of instance function(), <\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span style=\"color: gray;\">\/\/that starts the consequent call of iterations<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span style=\"color: #222222;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 setTimeout(step, instance);<\/span><\/p>\n<p class=\"MsoNormal\" style=\"vertical-align: baseline; word-break: break-all;\"><span style=\"color: #222222;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 };<\/span><\/p>\n<p><img class=\"herta\" src=\"http:\/\/www.iridiummobile.net\/new_include_areas\/img\/herta.png\" \/><\/p>\n<p>The code written by me allows to play music continually, without time-lags. And it\u2019s only one of the variants of using the code, written by James Edwards. Using it as a basis you can write your own self-adjusting timer for any purpose you want.<\/p>\n<p>You can read the original of the article, used as a starting point of this post, here: <a href=\"http:\/\/www.sitepoint.com\/creating-accurate-timers-in-javascript\/\" target=\"_blank\" rel=\"nofollow noopener\">\u0421reating accurate timers in JavaScript<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ilya Markov Script programmer at iRidium mobile The image to the post is a painting by Salvador Dali \u201cTime flows\u201d. The choice is not a<\/p>\n","protected":false},"author":2,"featured_media":948,"comment_status":"open","ping_status":"open","sticky":false,"template":"template-centered.php","format":"standard","meta":[],"categories":[3],"tags":[],"_links":{"self":[{"href":"https:\/\/blog.iridi.com\/en\/wp-json\/wp\/v2\/posts\/626"}],"collection":[{"href":"https:\/\/blog.iridi.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.iridi.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.iridi.com\/en\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.iridi.com\/en\/wp-json\/wp\/v2\/comments?post=626"}],"version-history":[{"count":3,"href":"https:\/\/blog.iridi.com\/en\/wp-json\/wp\/v2\/posts\/626\/revisions"}],"predecessor-version":[{"id":1183,"href":"https:\/\/blog.iridi.com\/en\/wp-json\/wp\/v2\/posts\/626\/revisions\/1183"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.iridi.com\/en\/wp-json\/wp\/v2\/media\/948"}],"wp:attachment":[{"href":"https:\/\/blog.iridi.com\/en\/wp-json\/wp\/v2\/media?parent=626"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.iridi.com\/en\/wp-json\/wp\/v2\/categories?post=626"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.iridi.com\/en\/wp-json\/wp\/v2\/tags?post=626"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}