{"action":"created","issue":{"url":"https://api.github.com/repos/visionmedia/page.js/issues/488","repository_url":"https://api.github.com/repos/visionmedia/page.js","labels_url":"https://api.github.com/repos/visionmedia/page.js/issues/488/labels{/name}","comments_url":"https://api.github.com/repos/visionmedia/page.js/issues/488/comments","events_url":"https://api.github.com/repos/visionmedia/page.js/issues/488/events","html_url":"https://github.com/visionmedia/page.js/pull/488","id":341242745,"node_id":"MDExOlB1bGxSZXF1ZXN0MjAxNDU1NDc5","number":488,"title":"Implement dispatching iteratively.","user":{"login":"sgomes","id":409615,"node_id":"MDQ6VXNlcjQwOTYxNQ==","avatar_url":"https://avatars1.githubusercontent.com/u/409615?v=4","gravatar_id":"","url":"https://api.github.com/users/sgomes","html_url":"https://github.com/sgomes","followers_url":"https://api.github.com/users/sgomes/followers","following_url":"https://api.github.com/users/sgomes/following{/other_user}","gists_url":"https://api.github.com/users/sgomes/gists{/gist_id}","starred_url":"https://api.github.com/users/sgomes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sgomes/subscriptions","organizations_url":"https://api.github.com/users/sgomes/orgs","repos_url":"https://api.github.com/users/sgomes/repos","events_url":"https://api.github.com/users/sgomes/events{/privacy}","received_events_url":"https://api.github.com/users/sgomes/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":7,"created_at":"2018-07-14T15:06:14Z","updated_at":"2018-07-17T10:07:36Z","closed_at":null,"author_association":"NONE","pull_request":{"url":"https://api.github.com/repos/visionmedia/page.js/pulls/488","html_url":"https://github.com/visionmedia/page.js/pull/488","diff_url":"https://github.com/visionmedia/page.js/pull/488.diff","patch_url":"https://github.com/visionmedia/page.js/pull/488.patch"},"body":"Hello, `page.js` maintainers! 👋 \r\n\r\nIn applications with a large number of middlewares, the recursive implementation of `nextEnter` and `nextExit` become a problem, by generating deep call stacks (2x the number of middlewares, as far\r\nas I can tell).\r\n\r\nEven where the call stack size isn't directly an issue, the added cruft to the call tree can make debugging and profiling harder.\r\n\r\nRecursive (note the many layers of `nextEnter`):\r\n\r\n![image](https://user-images.githubusercontent.com/409615/42725650-2aff0288-877f-11e8-82d8-d2fe8c92a056.png)\r\n\r\nIterative (note how there's a single layer of `nextEnter` now):\r\n\r\n![image](https://user-images.githubusercontent.com/409615/42725656-397127e2-877f-11e8-996e-834eba0f7353.png)\r\n\r\nThere doesn't seem to be a strong reason for these methods to be implemented recursively, so I reimplemented them iteratively.\r\n\r\nAll the tests work correctly, but please double-check the logic, and let me know if there's anything wrong with it, the coding style, or my commit in general.\r\n\r\nThanks for taking a look! 🙂 "},"comment":{"url":"https://api.github.com/repos/visionmedia/page.js/issues/comments/405530651","html_url":"https://github.com/visionmedia/page.js/pull/488#issuecomment-405530651","issue_url":"https://api.github.com/repos/visionmedia/page.js/issues/488","id":405530651,"node_id":"MDEyOklzc3VlQ29tbWVudDQwNTUzMDY1MQ==","user":{"login":"jsnajdr","id":664258,"node_id":"MDQ6VXNlcjY2NDI1OA==","avatar_url":"https://avatars3.githubusercontent.com/u/664258?v=4","gravatar_id":"","url":"https://api.github.com/users/jsnajdr","html_url":"https://github.com/jsnajdr","followers_url":"https://api.github.com/users/jsnajdr/followers","following_url":"https://api.github.com/users/jsnajdr/following{/other_user}","gists_url":"https://api.github.com/users/jsnajdr/gists{/gist_id}","starred_url":"https://api.github.com/users/jsnajdr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jsnajdr/subscriptions","organizations_url":"https://api.github.com/users/jsnajdr/orgs","repos_url":"https://api.github.com/users/jsnajdr/repos","events_url":"https://api.github.com/users/jsnajdr/events{/privacy}","received_events_url":"https://api.github.com/users/jsnajdr/received_events","type":"User","site_admin":false},"created_at":"2018-07-17T10:07:36Z","updated_at":"2018-07-17T10:07:36Z","author_association":"NONE","body":"However, I think there is still a chance to make it work. The idea is to detect if `next` was called synchronously:\r\n```js\r\nlet nextCalledSynchronously = false;\r\nwrappedNext = () => {\r\n  nextCalledSynchronously = true;\r\n  ...\r\n};\r\nhandler( context, wrappedNext );\r\nif ( nextCalledSychronously ) {\r\n  continueWithIteration();\r\n} else {\r\n  continueWithRecursion();\r\n}\r\n```\r\nand depending on the result, chains of synchronous `next` calls can be handled with a loop, and async calls can be handled with recursion as before.\r\n\r\nThat should still compress the call stacks very significantly as most handlers call `next` synchronously.\r\n"}}
{"actor":{"display_login":"jsnajdr"}}