Saya datang ke sini cukup nyaman dengan kedua konsep tersebut, tetapi dengan sesuatu yang tidak jelas bagi saya tentang keduanya.
Setelah membaca beberapa jawaban, saya rasa saya memiliki metafora yang benar dan berguna untuk menjelaskan perbedaannya.
Jika Anda menganggap baris kode individual Anda sebagai kartu remi yang terpisah tetapi teratur (hentikan saya jika saya menjelaskan cara kerja kartu punch jadul), maka untuk setiap prosedur terpisah tertulis, Anda akan memiliki tumpukan kartu yang unik (jangan salin & tempel!) dan perbedaan antara apa yang biasanya berjalan saat menjalankan kode secara normal dan secara asinkron bergantung pada apakah Anda peduli atau tidak.
Ketika Anda menjalankan kode, Anda menyerahkan OS satu set operasi tunggal (yang compiler atau interpreter Anda pecahkan kode level "lebih tinggi" Anda) untuk diteruskan ke prosesor. Dengan satu prosesor, hanya satu baris kode yang dapat dieksekusi dalam satu waktu. Jadi, untuk mencapai ilusi menjalankan banyak proses pada saat yang sama, OS menggunakan teknik di mana ia mengirimkan prosesor hanya beberapa baris dari proses tertentu pada satu waktu, beralih di antara semua proses sesuai dengan tampilannya. cocok. Hasilnya adalah beberapa proses yang menunjukkan kemajuan kepada pengguna akhir pada waktu yang tampaknya bersamaan.
Untuk metafora kita, hubungannya adalah OS selalu mengocok kartu sebelum mengirimnya ke prosesor. Jika tumpukan kartu Anda tidak bergantung pada tumpukan lain, Anda tidak menyadari bahwa tumpukan Anda berhenti dipilih saat tumpukan lain menjadi aktif. Jadi, jika Anda tidak peduli, itu tidak masalah.
Namun, jika Anda benar-benar peduli (misalnya, ada banyak proses - atau tumpukan kartu - yang saling bergantung satu sama lain), pengacakan OS akan mengacaukan hasil Anda.
Menulis kode asynchronous membutuhkan penanganan ketergantungan antara urutan eksekusi terlepas dari apa pengurutan itu akhirnya. Inilah mengapa konstruksi seperti "panggilan balik" digunakan. Mereka berkata kepada prosesor, "hal berikutnya yang harus dilakukan adalah memberi tahu tumpukan lain apa yang kami lakukan". Dengan menggunakan alat tersebut, Anda dapat yakin bahwa tumpukan lain akan diberi tahu sebelum memungkinkan OS untuk menjalankan lebih banyak instruksinya. ("If call_back == false: send (no_operation)" - tidak yakin apakah ini benar-benar cara penerapannya, tetapi secara logis, menurut saya ini konsisten.)
Untuk proses paralel, perbedaannya adalah Anda memiliki dua tumpukan yang tidak peduli satu sama lain dan dua pekerja untuk memprosesnya. Pada akhirnya, Anda mungkin perlu menggabungkan hasil dari dua tumpukan, yang kemudian akan menjadi masalah sinkronisitas tetapi, untuk eksekusi, Anda tidak peduli lagi.
Tidak yakin apakah ini membantu tetapi, saya selalu menemukan banyak penjelasan bermanfaat. Selain itu, perhatikan bahwa eksekusi asinkron tidak dibatasi ke komputer individual dan prosesornya. Secara umum, ini berkaitan dengan waktu, atau (bahkan lebih umum lagi) urutan peristiwa. Jadi jika Anda mengirim tumpukan dependen A ke node jaringan X dan tumpukan B yang digabungkan ke Y, kode asinkron yang benar harus dapat memperhitungkan situasi tersebut seolah-olah itu berjalan secara lokal di laptop Anda.