7 ms·
Here's my off-the-cuff take that will not be popular. A function like this should be a package. Or, really, part of standard js, maybe. A) The problem it solv
by staticassertion 6y ago
Here's my off-the-cuff take that will not be popular.
A function like this should be a package. Or, really, part of standard js, maybe.
A) The problem it solves is real. It's dumb, but JS has tons of dumb stuff, so that changes nothing. Sometimes you want to know "is this thing a promise", and that's not trivial (for reasons).
B) The problem it solves is not straightforward. If you Google around you'll get people saying "Anything with a .then is a promise' or other different ways of testing it. The code being convoluted shows that.
Should this problem be solved elsewhere? Sure, again, JavaScript is bad and no one's on the other side of that argument, but it's what we have. Is "just copy paste a wrong answer from SO and end up with 50 different functions in your codebase to check something" like other languages that make package management hard so much better ? I don't think so.
- degraafc 6y agoI'd say that it should rather be a part of the type system. Some kind of `obj isa Promise` should be the way to do this, not random property checks. But that's JS...
- staticassertion 6y agoI'm totally with you on this. It's dumb that this is a problem but it is actually a problem.
- odensc 6y agoIn theory `x instanceof Promise` would work, but the reason for this package is that there are many non-standard Promise implementations in the JS world.
- exogen 6y agoIt wouldn't work even if everything were native – see my reply above.
- kroltan 6y agoThe thing is that there is the Promise "class", which is provided by the environment, but there is a interface called PromiseLike, which is defined as having a method called then that takes one or two functions. Now, JS doesn't have nominal typing for interfaces, so you have to do "random property checks". Typescript partially solves that by declaring types, but if you have a any variable, you still need to do some probing to be able to safely convert it to a PromiseLike, because TypeScript goes to great lengths to not actually produce physical code on its output, attempting to be just a type checker. Perhaps if TS or an extension allowed "materializing" TS, that is `value instanceof SomeInterface` generated code to check for the existence of appropriate interface members, this could be avoided, but alas, this is not the case.
- ehsankia 6y agoshouldn't it then be called is-promise-like? Also, if you're being loose about it anyways, can't you simply just go for `if (obj && typeof obj.then == 'function')` and call it a day? I'd say that's short enough to include your own version and not rely on a package for. I think that module over complicates it as it is, and most people don't need that level of complication in their code.
- zbentley 6y ago> Perhaps if TS or an extension allowed "materializing" TS, that is `value instanceof SomeInterface` generated code to check for the existence of appropriate interface members, this could be avoided It's not perfect and a bit of a bolt-on, but io.ts works reasonably well in this area: https://github.com/gcanti/io-ts https://github.com/gcanti/io-ts
- city41 6y agoPromises were not always part of the standard and for many years were implemented in user space, by many different implementations. Using duck typing like this was the only way to allow packages to interact with each other, as requiring an entire stack to say only use Bluebird promises is not realistic at all.
- mikewhy 6y ago> Or, really, part of standard js, maybe.see: It's a part of node, at least: https://nodejs.org/docs/latest-v12.x/api/util.html#util_util_types_ispromise_value https://nodejs.org/docs/latest-v12.x/api/util.html#util_util...
- staticassertion 6y agoThis will work for a standard Promise, which is great, but not for weirdo made up promises. It also was released, I think, in 2018. It's one thing if you own the entire codebase, but if you're building a popular, multiple-years-old library/framework, you can't make the same assumptions.
- mikewhy 6y agoI'm only finding about it today TBH. Usually I go for what this library does: function isPromise(obj) { return typeof obj?.then === 'function' }
- alerighi 6y agoLile... x instanceof Promise It works for standard promises, sure there are non standard promises, ancient stuff, that to me shouldn't be used (and a library that uses them should be avoided). So why you need that code in the first place? Also that isPromise function will not work with TypeScript, imagine you have a function that takes something that can be a promise or not (and this is also bad design in the first place), but then you want to check if the argument is a Promise, sure with `instanceof` the compiler knows that you are doing, otherwise not. Also, look at the repo, a ton of files for a 1 line function? Really? You take less time to write that function yourself than to include that library. But you shouldn't have to write that function in the first place.
- staticassertion 6y ago1) I'm not defending the implementation of is-promise. I don't care to, I'm not a javascript developer. 2) > sure there are non standard promises, ancient stuff, that to me shouldn't be used If you're building a library, or maintaining one that's been built over many years, you can't easily make calls like that.
- dragonwriter 6y ago> If you're building a library, or maintaining one that's been built over many years, you can't easily make calls like that. Well, you can, and in the JS ecosystem you'll often find cases where there are two libraries (or two broad classes of libraries) for a certain function that make different choices, one of which makes the simple, modern choice that doesn't support legacy, and one that does the complex, messy thing necessary to deal with legacy code, and which you use depends on your project and it's other constraints.
- staticassertion 6y agoOK, then the legacy library can't easily make that choice. I'm not saying every single javascript developer should be accepting async or sync callbacks, just that some libraries are choosing to do that for legitimate reasons.
- drinchev 6y agoYeah, but the question is how far should we go with that. Should we do : const isFalsy = require("is-falsy"); const isObject = require("is-object"); const isFunction = require( "is-function" ); const hasThen = require( "has-then" ); function isPromise(obj) { return !isFalsy(obj) && ( isObject(obj) || isFunction(obj) ) && hasThen( obj ); } Just because the code line is more than 50 characters, doesn't mean that we need a new library for that.
- enitihas 6y agoI think all of the above might already be libraries on npm. From what I remember, npm has isInteger, isPositive, is-odd, is-even.
- recursive 6y agoAll of the packages you mentioned are maintained by the same guy.
- sergiotapia 6y agoHave you seen his twitter? It's incredibly cringey. I don't understand how someone could be so arrogant to claim millions of companies use his software, when his software is isFalse. Not to mention his hundreds of packages that literally just output an emoji.
- artificial 6y agoReminds me of Dr. Evil’s monologue about his Father making ridiculous claims about inventing the question mark.
- dragonwriter 6y agoisFalsy is just “!”; I don't think we need a new library for a more verbose way to express a one-character unary operator, no, nor does it meet the standard of “The problem it solves is not straightforward” proposed upthread.
- jhanschoo 6y agoI don't think it should be a package. One-liners without dependencies like this should live as a function in a utility file. If justification is needed, there should be a comment with a link to this package's repo.
- Pfhreak 6y agoWhat's the difference between a utility file and a package? That seems like a distinction without a difference to me. If you use the same one liners in more than one project and you copy that utility file over, the line gets even fuzzier.
- Ndymium 6y agoThe utility file will never be updated and break your build without you doing it yourself.
- hombre_fatal 6y agoAlso you can just read the code the same way you read any other code. And since it's in your codebase and git diffs, you will read it. Because the implementation detail of is-promise actually is important. It just checks if an object has a .then() method. So if you use it, it's just as important that you know the limitation. Not everything needs to be swept under the rug.
- darekkay 6y agoAlso: The utility file will never be updated and fix existing issues within the utility itself (unless you look up the package and diff it yourself). It's a trade-off.
- jhanschoo 6y agoAs the commenter who suggested keeping it in a utilities file, I'd say that the trade-off is heavily weighted to not importing it as a package. When you cribbed the code you should have completely understood what exactly the package was doing, and why, and known what issues it would have had. Since it's a one-liner, it is transparent. Since it is without dependencies, it is unlikely to fail on old code. So it's unlikely to have existing issues and unlikely to develop new issues. Of course, if you end up using new features of the language in your code, it may fail on that, but the risk old stuff failing should have already been factored in when you decided to upgrade. In fact, the one-liner solves this better since you decide the pace of adaptation of your one-liner to the new features, not the package maintainer.
- devit 6y agoA function like this should not be something that anyone even thinks of writing or using. In properly designed languages, values have either a known concrete type, or the interfaces that they have to support are listed, and the compiler checks them. Even in JavaScript/TypeScript, if you are using this, you or a library you are using are doing it wrong, since you should know whether a value is a promise or not when writing code.
- city41 6y agoThis function is most likely an artifact of before promises got standardized. One way promises took off and became so ubiquitous is different implementations could interop seamlessly. And the reason for that is a promise was defined as 'an object or function having a then method which returns a promise when called'. Doesn't excuse the JS ecosystem and JS as a whole, which truly is a mess. But there's a history behind these things.
- stefan_ 6y agoI think the point of the comment is: you should not be testing for this at all. If your API works with promises, call .then() on what is handed to you. That's it. Don't make up emergent, untestable behavior on the spot.
- city41 6y agoYou need to do this test if you are creating a promise implementation. That was my point, there is a reason code like this exists.
- earthboundkid 6y agoWhy would an implementation need to test for it? ISTM that a framework may need to test for promiseness if it calls promises and functions differently, but it can and should be done as a utility in the framework, not as a separate package.
- drngdds 6y ago>Or, really, part of standard js, maybe. I think this would be the solution. I feel like a lot of the NPM transitive dependency explosion just comes from the fact that JavaScript is a language with a ton of warts and a lack of solid built-ins compared to e.g. Python. Python also has packages and dependencies, but the full list of dependencies used by a REST service I run in production (including a web framework and ORM) is a million times smaller than any package-lock.json I've seen.
- jdminhbg 6y agoThis is correct. I post the same thing every time one of these JS dependency hell issues pops up, but it's the case because it's true: The problem is the lack of a standard library. It's not that people don't know how to write a left-pad function, it's that it's dumb to rewrite it in every project and then remember what order you put the arguments in, etc. So people standardize, but they're standardizing on millions of different little packages. I think the effort that goes into all the JS syntax and module changes would be better put into developing a solid standard library first.
- galoisgirl 6y agoThere's a rich standard library, you don't need a package to left-pad.
- grumple 6y agoThis function should absolutely NOT be a package. The problem is that JS has a very minimal standard library and despite tons of money going into the system, nobody's had the good sense to take a leadership role and implement that standard. In other languages you don't need to include external packages to determine the types of objects you're dealing with, or many other things.
- detaro 6y agoAnd there's an interesting discussion to be had if it shouldn't be one of those snippets that everyone copies from Stackoverflow instead. And how much trouble in other ways that alternative has caused.
- wolco 6y agoShouldn't a js framework exist that includes these static basic if checks in the core and offers them as a buildin method? Why load this as an external package, why not copy the code and maintain locally?
- Thorentis 6y agoI think you're on the right track. We all (I hope) agree that stuff like this should be standardized. But that's not the same as "should be a package". At the very least, W3, or Mozilla Foundation, or something with some kind of quasi-authority should release a "JS STD" package that contains a whole bunch of helper functions like this. Or maybe a "JS Extras" package, and as function usage is tracked across the eco-system, the most popular/important stuff is considered for addition into the JS standard itself. Having hundreds of packages that each contain one line functions, simply means that there are hundreds of vectors by which large projects can break. And those can in turn break other projects, etc. The reason, cynically, that these all exist as separate packages, is because the person who started this fiasco wanted to put a high a download count as possible on his resume for packages he maintains. Splitting everything up into multiple packages means extra-cred for doing OSS work. Completely stupid, and I'm annoyed nobody has stepped up with a replacement for all this yet.
- forty 6y agoNo. There is no reason why it should be a package by itself. It should be part of a bigger util package, which which is well maintained, tested, and with many maintainers actively looking at it, with good processes, such as systematic code reviews, etc. At work, our big webapp depended at some point indirectly on "isobject" "isobj" and "is-object", which were all one liners (some of them even had dependencies themselves!!). Please let's all just depend on lodash and it will actually eventually reduce space and bandwith usage.
- therealdrag0 6y agoYep, in Java-land this would be in an Apache Common's (or Guava, etc) module with dozens and dozens of other useful functionality.