{"action":"created","issue":{"url":"https://api.github.com/repos/petkaantonov/bluebird/issues/481","labels_url":"https://api.github.com/repos/petkaantonov/bluebird/issues/481/labels{/name}","comments_url":"https://api.github.com/repos/petkaantonov/bluebird/issues/481/comments","events_url":"https://api.github.com/repos/petkaantonov/bluebird/issues/481/events","html_url":"https://github.com/petkaantonov/bluebird/issues/481","id":56551440,"number":481,"title":"Feature Request: Add utility function for serially chaining handlers and returning the first resolved value","user":{"login":"timhuff","id":609217,"avatar_url":"https://avatars.githubusercontent.com/u/609217?v=3","gravatar_id":"","url":"https://api.github.com/users/timhuff","html_url":"https://github.com/timhuff","followers_url":"https://api.github.com/users/timhuff/followers","following_url":"https://api.github.com/users/timhuff/following{/other_user}","gists_url":"https://api.github.com/users/timhuff/gists{/gist_id}","starred_url":"https://api.github.com/users/timhuff/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/timhuff/subscriptions","organizations_url":"https://api.github.com/users/timhuff/orgs","repos_url":"https://api.github.com/users/timhuff/repos","events_url":"https://api.github.com/users/timhuff/events{/privacy}","received_events_url":"https://api.github.com/users/timhuff/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":13,"created_at":"2015-02-04T16:37:42Z","updated_at":"2015-02-04T17:55:33Z","closed_at":null,"body":"I'm frequently in a position where, in an attempt to acquire some resource, I want to say \"Try this. If that doesn't work, try this. If that doesn't work, try this\". It'd be nice to be able to write:\r\n```javascript\r\nPromise.first(params, [\r\n    method1,\r\n    method2,\r\n    method3\r\n]).then(function(value){\r\n//do something with value\r\n})\r\n```\r\n\r\nIt appears that, currently, you can get bluebird to have this desired behavior, but it's not very clean and requires either having a helper function laying around or a bunch of unnecessary code.\r\n\r\nI believe there are many use-cases for such a utility function. It would be useful any time when there's a preferred method of acquiring a resource and then one or more alternate methods, that are perhaps less efficient. An example of a use case for this would be:\r\n```javascript\r\nfunction findStudents(query){\r\n\tPromise.first(query, [\r\n\t\tStudents.findById\r\n\t\tStudents.findByTeacher\r\n\t\tStudents.findByMajor\r\n\t])\r\n\t.then(function(students){\r\n\t\t//do something with students\r\n\t})\r\n}\r\n```\r\n\r\nMy use-case that inspired this request is a reverse image lookup. Sometimes I'll have an exact match on SHA256 hash if that doesn't work, sometimes I'll have a close match on our proprietary image hash, and if that doesn't work and I can't find any matches, I'll upload the file and then say \"ok, NOW it exists, here it is\".\r\n\r\nA rough implementation of the behavior I had in mind would be\r\n```coffee\r\nPromise.first = (args..., methods=[], thisArg)->\r\n\tif methods.length == 0\r\n\t\treturn Promise.resolve()\r\n\terrors = new Promise.AggregateError\r\n\tfirstResolvedMethod = (n=0)->\r\n\t\tmethods[n].apply thisArg, args\r\n\t\t.error (error)->\r\n\t\t\terrors.push error\r\n\t\t\tif n < methods.length-1\r\n\t\t\t\treturn firstResolvedMethod n+1\r\n\t\t\telse\r\n\t\t\t\treturn Promise.reject errors\r\n\treturn firstResolvedMethod()\r\n```\r\n\r\nThis topic was discussed [here](https://github.com/petkaantonov/bluebird/issues/480) a little but I kind of botched the whole thing up by not thinking carefully enough about it beforehand. I created a new issue in the hopes of having a more structured discussion on the topic."},"comment":{"url":"https://api.github.com/repos/petkaantonov/bluebird/issues/comments/72903911","html_url":"https://github.com/petkaantonov/bluebird/issues/481#issuecomment-72903911","issue_url":"https://api.github.com/repos/petkaantonov/bluebird/issues/481","id":72903911,"user":{"login":"timhuff","id":609217,"avatar_url":"https://avatars.githubusercontent.com/u/609217?v=3","gravatar_id":"","url":"https://api.github.com/users/timhuff","html_url":"https://github.com/timhuff","followers_url":"https://api.github.com/users/timhuff/followers","following_url":"https://api.github.com/users/timhuff/following{/other_user}","gists_url":"https://api.github.com/users/timhuff/gists{/gist_id}","starred_url":"https://api.github.com/users/timhuff/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/timhuff/subscriptions","organizations_url":"https://api.github.com/users/timhuff/orgs","repos_url":"https://api.github.com/users/timhuff/repos","events_url":"https://api.github.com/users/timhuff/events{/privacy}","received_events_url":"https://api.github.com/users/timhuff/received_events","type":"User","site_admin":false},"created_at":"2015-02-04T17:55:33Z","updated_at":"2015-02-04T17:55:33Z","body":"@spion Yea, I just realized I can do that and it's so simple. I've been using bluebird (and prior promise libraries) for some time now. Had a major \"whoosh\" moment. It prevents a few niceties like that `AggregatedError` but it's much simpler. I still think having an `.else` syntactic sugar for that might be nice."}}