No, not really at all.
Asynchronous means something happens outside of the main flow of the program and doesn’t block the program from running whilst waiting for it to happen. So for example, you send a request to a remote server. A response can’t come back immediately unless you break the laws of physics. So either you wait for the response and block everything anything else from occurring in the program (synchronous), or you allow the program to continue and deal with the response when it arrives (asynchronous).
Threads are very small parts of a program that are dealt with by the programming language runtime (or the operating system) scheduler. They tend to have access to (share) some common state (which is where the complexity comes in). If you have multiple cores, the scheduler can run as many threads as there are cores at literally the same time (in parallel). If you don’t, the scheduler can (as long as they don’t do too much) rapidly switch between threads to make it appear that the things they are doing are almost happening in parallel.
JS has a thing called the event loop, and it uses callbacks for asynchronous code (concurrency). Your code runs, top to bottom, every time. If there’s a callback, it registers it, and calls that once it gets to the bottom. And then if that triggers another callback, then that gets called and so on and so forth.
Note that in the browser, the JS API can use WebWorkers to create multiple processes (kinda the next size up from threads), so you can shift processing of tasks off the main operating system thread. There have also been a few threading libraries for Node (Node is written in C++, and Node allows use of extensions written in that language), but they didn’t gain much traction as they basically break how JS works. JS itself does not allow multithreading.