Calc
calc adalah fungsi asinkron yang ingin kami lakukan analisis (analisis kinerja). Dengan konvensi, parameter terakhirnya adalah callback . Kami menggunakan calc seperti ini:
calc (arg, (err, res) => console.log (err || res))
Mungkin cara termudah untuk menganalisis kinerja pada fungsi seperti calc adalah dengan menambahkan logika waktu ke tempat yang perlu kita analisis:
const t0 = date.now () calc (arg, (err, res) => {const t1 = date.now () console.log (`log: waktu: $ {t1 = t0}`) console.log (err || res)})) Namun, ini bukan solusi yang dapat digunakan kembali. Setiap kali kami ingin menghitung waktu suatu fungsi, kami harus memperkenalkan T0 di ruang lingkup luar dan mengubah callback untuk mengukur dan mencatat waktu.
Cara yang ideal bagi saya adalah dengan dapat mengatur waktu hanya dengan membungkus fungsi asinkron:
timeit (calc) (arg, (err, res) => console.log (err || res))
timeIt harus dapat melakukan analisis dan merekam waktu eksekusi untuk setiap fungsi asinkron dengan baik.
Perhatikan bahwa timeIt(calc) memiliki tanda tangan yang sama dengan fungsi Calc Function, yaitu, mereka menerima parameter yang sama dan mengembalikan nilai yang sama, itu hanya menambahkan fitur ke CALE (fitur yang dapat direkam waktu).
Calc dan TimeIt (Calc) dapat diganti satu sama lain kapan saja.
timeIt sendiri adalah fungsi orde tinggi karena menerima fungsi dan mengembalikan fungsi. Dalam contoh kami, ia menerima fungsi Calc Asynchronous dan mengembalikan fungsi dengan parameter yang sama dan nilai pengembalian seperti Calc.
Berikut ini menunjukkan bagaimana kami mengimplementasikan fungsi TimeIt:
const timeIt = R.curry((report, f) => (...args) => { const t0 = Date.now() const nArgs = R.init(args) const callback = R.last(args) nArgs.push((...args) => { const t1 = Date.now() callback(...args) report(t1 - t0, ...args) }) f(...nArgs)})const timeIt1 = timeIt( (t, err, res) => console.log(`Log: ${err || res} produced after: ${t}`))const calc = (x, y, z, callback) => setTimeout(() => callback(null, x * y / z), 1000)calc(18, 7, 3, (err, res) => console.log(err || res)) timeit1 (calc) (18, 7, 3, (err, res) => console.log (err || res)) Implementasi timeIt ini menerima dua parameter:
Laporan: Fungsi digunakan untuk menghasilkan hasil analisis
F: Fungsi asinkron kami ingin melakukan analisis
timeIt1 adalah fungsi yang nyaman dan praktis, hanya menggunakan console.log untuk merekam hasil pengukuran waktu. Kami mendefinisikannya dengan meneruskan parameter report ke fungsi timeIt yang lebih umum.
Kami mencapai tujuan, dan sekarang kami bisa membungkus fungsi asinkron di timeIt1 dan waktu sudah waktunya:
timeit1 (calc) (18, 7, 3, (err, res) => console.log (err || res))
Fungsi General timeIt menerima fungsi Callback report dan fungsi asinkron dan mengembalikan fungsi asinkron baru. Fungsi asinkron ini memiliki parameter yang sama dan nilai pengembalian seperti fungsi asli. Kita bisa menggunakan ini:
timeit ((waktu, ... hasil) => // Laporkan panggilan balik: logam, asyncfunc) (parameter ..., (... hasil) => // hasil fungsi async)
Sekarang mari selami implementasi timeIt . Kami dapat dengan mudah menghasilkan fungsi umum seperti timeIt1 , karena timeIt dikorbankan menggunakan R.curry .
Saya tidak berencana untuk membahas korikulisasi dalam posting ini, tetapi kode berikut menunjukkan penggunaan utama korikulisasi:
const f = r.curry ((x, y) => x + y) f (1, 10) // == 11f (1) (10) // == 11const plus1 = f (1) plus1 (10) // == 11
Di sisi lain, ada beberapa masalah dengan waktu yang diterapkan dengan cara ini:
(... args) => {const t1 = date.now () callback (... args) laporan (t1 - t0, ... args)} Ini adalah fungsi anonim (juga dikenal sebagai lambda, callback) yang dipanggil setelah fungsi asli dieksekusi secara tidak sinkron. Masalah utama adalah bahwa fungsi ini tidak memiliki mekanisme untuk menangani pengecualian. Jika callback melempar pengecualian, report tidak akan pernah dipanggil.
Kami dapat menambahkan try / catch ke fungsi lambda ini, tetapi akar masalahnya adalah bahwa callback dan report adalah dua fungsi void , dan mereka tidak terkait. timeIt berisi dua kelanjutan ( report dan callback ). Jika kami hanya merekam waktu eksekusi di bawah console atau jika kami yakin bahwa tidak ada report atau callback tidak akan melempar pengecualian, maka semuanya baik -baik saja. Tetapi jika kita ingin melakukan beberapa perilaku berdasarkan hasil analisis (yang disebut penskalaan otomatis) maka kita perlu memperkuat dan mengklarifikasi urutan kelanjutan dalam program kami.
Oke, saya harap konten lengkap dari artikel ini akan membantu untuk belajar dan bekerja semua orang. Jika Anda memiliki pertanyaan, Anda dapat meninggalkan pesan untuk berkomunikasi.