Rumah  >  Artikel  >  hujung hadapan web  >  Lihat secara mendalam kaedah promisify() modul util Node.js

Lihat secara mendalam kaedah promisify() modul util Node.js

青灯夜游
青灯夜游ke hadapan
2021-08-27 10:33:233176semak imbas

Lihat secara mendalam kaedah promisify() modul util Node.js

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'

Bagaimanakah janji janji berfungsi? Bagaimanakah

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

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!

Kenyataan:
Artikel ini dikembalikan pada:juejin.cn. Jika ada pelanggaran, sila hubungi admin@php.cn Padam