Node の util.promisify() 関数の詳細な分析

青灯夜游
リリース: 2023-04-12 17:56:15
転載
1323 人が閲覧しました

Node.js の組み込み util パッケージには、コールバック ベースの関数を Promise ベースの関数に変換できる promisify() 関数があります。この記事では、Node.js の util.promisify() 関数について紹介します。

Node の util.promisify() 関数の詳細な分析

コールバックベースの API で Promisechaining および async/await を使用できるようにします。

たとえば、Node.js の fs パッケージ はコールバックを使用します。通常、ファイルを読み取るにはコールバックを使用する必要があります。

const fs = require('fs');
fs.readFile('./package.json', function callback(err, buf) {
    const obj = JSON.parse(buf.toString('utf8'));
    obj.name; // 'masteringjs.io'
});
ログイン後にコピー

util.promisify() を使用して、fs.readFile() 関数をPromise を返す関数。 [関連チュートリアルの推奨事項: nodejs ビデオ チュートリアル プログラミング教育 ]

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'));
obj.name; // 'masteringjs.io'
ログイン後にコピー

簡単な実装

util.promisify()内部的にはどのように機能するのでしょうか? npm にはポリフィル があり、ここで 完全な実装を読むことができます。 ここで Node.js 実装を見つけることもできます が、教育目的の場合はポリフィルの方が読みやすいです。

util.promisify()

基本的な考え方は、渡したパラメータに基づいて コールバック関数を追加するです。このコールバック関数は、promise 関数によって返された Promise を解決または拒否します。 これは少し冗長ですが、以下は

util.promisify()

メソッドの簡略化された実装バージョンです。

const fs = require('fs');

// `util.promisify()` 的简化实现。不涵盖所有情况,不要在生产环境中使用!
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) {
                    return reject(err);
                }
                resolve(res);
            }]));
        });
    }
}

// 将 `fs.readFile()` 转换为一个函数,该函数接受相同的参数但返回一个 Promise
const readFile = util.promisify(fs.readFile);

// 现在可以对 `readFile()` 使用 `await` 了!
const buf = await readFile('./package.json');

const obj = JSON.parse(buf.toString('utf8'));
obj.name; // 'masteringjs.io'
ログイン後にコピー
どうやって理解すればいいでしょうか?まず、

util.promisify()

は、渡したパラメーターに 1 つの追加パラメーターを追加し、これらの新しいパラメーターを使用して元の関数を呼び出します。次に、基になる関数がこれらの数のパラメータ呼び出しをサポートする必要があります。例: [String, Object] 型の 2 つのパラメータを使用して約束された関数 myFn() を呼び出す場合は、次のようにしてください。確かにプリミティブ関数は呼び出しシグネチャ [String, Object, Function] をサポートしています。 2 番目に、

util.promisify()

関数コンテキストに影響を与えます。 Losing Context

Losing Context

関数の呼び出し時に内部の this 値が正しくないことを示します。コンテキストの喪失は、変換された関数の一般的な問題です。

class MyClass {
  myCallbackFn(cb) {
    cb(null, this);
  }
}

const obj = new MyClass();
const promisified = require('util').promisify(obj.myCallbackFn);

const context = await promisified();
context; // 打印 `undefined` 而非 `MyClass` 实例!
ログイン後にコピー

this は、関数が呼び出されたオブジェクト を表します。したがって、約束された関数を同じオブジェクトのプロパティに設定することでコンテキストを保持できます。

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();
context === obj; // true
ログイン後にコピー
ノード関連の詳細については、nodejs チュートリアル

を参照してください。

以上がNode の util.promisify() 関数の詳細な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:juejin.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!