{"action":"created","issue":{"url":"https://api.github.com/repos/kriskowal/q/issues/785","repository_url":"https://api.github.com/repos/kriskowal/q","labels_url":"https://api.github.com/repos/kriskowal/q/issues/785/labels{/name}","comments_url":"https://api.github.com/repos/kriskowal/q/issues/785/comments","events_url":"https://api.github.com/repos/kriskowal/q/issues/785/events","html_url":"https://github.com/kriskowal/q/issues/785","id":161738043,"number":785,"title":"Q.timeout does not reject wrapped promise","user":{"login":"danilotsr","id":670284,"avatar_url":"https://avatars.githubusercontent.com/u/670284?v=3","gravatar_id":"","url":"https://api.github.com/users/danilotsr","html_url":"https://github.com/danilotsr","followers_url":"https://api.github.com/users/danilotsr/followers","following_url":"https://api.github.com/users/danilotsr/following{/other_user}","gists_url":"https://api.github.com/users/danilotsr/gists{/gist_id}","starred_url":"https://api.github.com/users/danilotsr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/danilotsr/subscriptions","organizations_url":"https://api.github.com/users/danilotsr/orgs","repos_url":"https://api.github.com/users/danilotsr/repos","events_url":"https://api.github.com/users/danilotsr/events{/privacy}","received_events_url":"https://api.github.com/users/danilotsr/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2016-06-22T17:15:09Z","updated_at":"2016-06-22T17:53:56Z","closed_at":"2016-06-22T17:53:56Z","body":"See the following code example:\r\n\r\n```\r\nvar Q = require('q');\r\n\r\nvar i = 0;\r\nvar DELAY = 100;\r\n\r\nvar loop = function() {\r\n  console.log('loop', i++);\r\n  return Q.delay(DELAY).then(loop);\r\n};\r\n\r\nvar originalPromise = loop();\r\noriginalPromise\r\n  .timeout(1000)\r\n  .catch(\r\n    function(error) {\r\n      console.log(error, 'originalPromise', originalPromise.inspect());\r\n    }\r\n  );\r\n```\r\n\r\nRunning this code would print\r\n\r\n```\r\nloop 0\r\nloop 1\r\n...\r\nloop 9\r\n[Error: Timed out after 1000 ms] 'originalPromise' { state: 'pending' }\r\nloop 10\r\nloop 11\r\n... it would keep going on and on\r\n```\r\n\r\nThere are two promise instances: `originalPromise` and the one returned by `.timeout(1000)`, let's call it `timeoutPromise`. This code runs fine in a sense that the promise chain would be interrupted after the set timeout of 1 second given that `timeoutPromise` would be rejected. However, the problem is that `originalPromise` isn't resolved, and it will never be resolved, therefore the loop keeps going on forever. Ideally, we would be able to inform `originalPromise` that it too should be rejected so that the loop can get interrupted."},"comment":{"url":"https://api.github.com/repos/kriskowal/q/issues/comments/227824579","html_url":"https://github.com/kriskowal/q/issues/785#issuecomment-227824579","issue_url":"https://api.github.com/repos/kriskowal/q/issues/785","id":227824579,"user":{"login":"kriskowal","id":60294,"avatar_url":"https://avatars.githubusercontent.com/u/60294?v=3","gravatar_id":"","url":"https://api.github.com/users/kriskowal","html_url":"https://github.com/kriskowal","followers_url":"https://api.github.com/users/kriskowal/followers","following_url":"https://api.github.com/users/kriskowal/following{/other_user}","gists_url":"https://api.github.com/users/kriskowal/gists{/gist_id}","starred_url":"https://api.github.com/users/kriskowal/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kriskowal/subscriptions","organizations_url":"https://api.github.com/users/kriskowal/orgs","repos_url":"https://api.github.com/users/kriskowal/repos","events_url":"https://api.github.com/users/kriskowal/events{/privacy}","received_events_url":"https://api.github.com/users/kriskowal/received_events","type":"User","site_admin":false},"created_at":"2016-06-22T17:53:56Z","updated_at":"2016-06-22T17:53:56Z","body":"This is behaving as designed. The timeout method (as with any other Q method) does not alter the state of the wrapped promise, which would constitute a plan interference hazard. Only the resolver has the power to reject the promise and the timeout method has no access to that capability. If you wish to be informed of the timeout, you must capture the timeout promise instead of the wrapped promise. This can be done by bringing the timeout into the loop around the work per iteration that must be accomplished in a timely fashion for the loop to continue."}}
{"actor":{"display_login":"kriskowal"}}