Node.js Modul util
terbina dalam mempunyai kaedah promisify()
yang menukar fungsi berasaskan panggil balik kepada Fungsi janji. Ini membolehkan anda menggunakan rantai Promise dan async/await
dengan API berasaskan panggil balik.
Sebagai contoh, modul fs
Node.js perlu menggunakan panggilan balik semasa membaca fail:
const fs = require('fs') fs.readFile('./package.json', function callback(err, buf) { const obj = JSON.parse(buf.toString('utf8')) console.log(obj.name) // 'Example' -> package.json 包名 })
Kita boleh menggunakan util.promisify()
untuk menukar fungsi panggil balik fs.readFile()
fungsi Return Promise:
const fs = require('fs') const util = require('util') // 将 fs.readFile() 转换为一个接受相同参数但返回 Promise 的函数。 const readFile = util.promisify(fs.readFile) // 现在可以将 readFile() 与 await 一起使用! const buf = await readFile('./package.json') const obj = JSON.parse(buf.toString('utf8')) console.log(obj.name) // 'Example'
util.promisify()
berfungsi di belakang tabir? Terdapat polyfill pada npm dan anda boleh membaca pelaksanaan penuh di sini. Anda juga boleh menemui Pelaksanaan Node.js di sini, tetapi untuk memudahkan pemahaman, polyfill lebih mudah dibaca. [Pembelajaran yang disyorkan: "tutorial nodejs"] Idea utama di sebalik
util.promisify()
ialah untuk menambah fungsi panggil balik pada parameter masuk. Fungsi panggil balik ini menyelesaikan atau menolak Janji yang dikembalikan oleh fungsi yang dijanjikan.
Untuk memudahkan pemahaman, berikut ialah contoh pelaksanaan tersuai util.promisify()
yang sangat ringkas:
const fs = require('fs') // util.promisify() 的简化实现。不包括所有情况,不要在 prod 环境中使用此选项! function promisify(fn) { return function() { const args = Array.prototype.slice.call(arguments) return new Promise((resolve, reject) => { fn.apply(this, [].concat(args).concat([(err, res) => { if (err != null) { return reject(err) } resolve(res) }])) }) } } // 将 fs.readFile() 转换为一个接受相同参数但返回 Promise 的函数。 const readFile = promisify(fs.readFile) // 现在可以将 readFile() 与 await 一起使用! const buf = await readFile('./package.json') const obj = JSON.parse(buf.toString('utf8')) console.log(obj.name) // 'Example'
Jadi apakah maksudnya? Mula-mula, util.promisify()
menambah 1 parameter tambahan pada parameter yang diluluskan dan kemudian memanggil fungsi asal dengan parameter baharu ini. Ini bermakna fungsi asas perlu menyokong bilangan parameter tersebut. Jadi jika anda memanggil myFn()
fungsi yang dijanjikan [String, Object]
dengan 2 jenis parameter, pastikan fungsi asal menyokong [String, Object, Function]
.
Jadi apa maksudnya? Mula-mula, util.promisify()
menambah parameter tambahan pada parameter yang diluluskan dan kemudian memanggil fungsi asal dengan parameter baharu ini. Ini bermakna fungsi asas perlu menyokong bilangan parameter tersebut. Jadi jika anda memanggil fungsi yang dijanjikan [String, Object]
dengan 2 argumen jenis myFn()
, pastikan fungsi asal menyokong [String, Object, Function]
.
Kedua, util.promisify()
mempunyai kesan pada konteks fungsi (this
).
Konteks yang hilang (this
) bermakna panggilan fungsi berakhir dengan nilai yang salah. Kehilangan konteks ialah masalah biasa dengan fungsi penukaran:
class MyClass { myCallbackFn(cb) { cb(null, this) } } const obj = new MyClass() const promisified = require('util').promisify(obj.myCallbackFn) const context = await promisified() console.log(context) // 打印 undefined 而不是 MyClass 实例!
Ingat bahawa this
ialah sebarang objek yang mengandungi sifat apabila fungsi dipanggil. Oleh itu, anda boleh mengekalkan konteks dengan menetapkan fungsi yang dijanjikan kepada sifat objek yang sama:
class MyClass { myCallbackFn(cb) { cb(null, this) } } const obj = new MyClass() // 保留上下文,因为 promisified 是 obj 的属性 obj.promisified = require('util').promisify(obj.myCallbackFn) const context = await obj.promisified() console.log(context === obj) // true
Untuk lebih banyak pengetahuan berkaitan pengaturcaraan, sila lawati: Video Pengaturcaraan! !
Atas ialah kandungan terperinci Lihat secara mendalam kaedah promisify() modul util Node.js. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!