Async JS code is parallel too. For example, await Promise.all(...) will wait on multiple functions at once. The JS event loop is only going to interpret one statement at a time, but in the meantime, other parts of the computer (file handles, TCP/IP stack, maybe even GPU/CPU depending on the JS lib) are actually doing things fully in parallel. A more useful distinction would be, the JS interpreter is single-threaded while C code can be multithreaded.
I can't think of anything in practice that's concurrent but not parallel. Not even single-core CPU running 2 threads, since again they can be using other resources like disk in parallel, or even separate parts of the CPU itself via pipelining.
> A more useful distinction would be, the JS interpreter is single-threaded while C code can be multithreaded.
...this seems like a long way round to say "JS code is not parallel while C code can be parallel".
Or to put it another way, it seems fairly obvious to me that parallelism is a concept applied to one's own code, not all the code in the computer's universe. Other parts of the computer doing other things has nothing to do with the point, or "parallelism" would be a completely redundant concept in this age where nearly every CPU has multiple cores.
But I've never heard of someone caring about their code vs lower-level code running in parallel, just whether or not there are multiple OS threads involved in the end. Like you have 32 CPU cores, your Python batch code is only using 1, and whether or not you use Python threads to fix this depends on if you're using something like Numpy that'll release the GIL.
I can't think of anything in practice that's concurrent but not parallel. Not even single-core CPU running 2 threads, since again they can be using other resources like disk in parallel, or even separate parts of the CPU itself via pipelining.