ホームページ  >  記事  >  ウェブフロントエンド  >  Node の util.promisify() 関数の詳細な分析

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

青灯夜游
青灯夜游転載
2023-04-12 17:56:151387ブラウズ

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()

メソッドの簡略化された実装バージョンです。 <pre class="brush:js;toolbar:false;">const fs = require(&amp;#39;fs&amp;#39;); // `util.promisify()` 的简化实现。不涵盖所有情况,不要在生产环境中使用! function promisify(fn) { return function () { const args = Array.prototype.slice.call(arguments); return new Promise((resolve, reject) =&gt; { fn.apply(this, [].concat(args).concat([(err, res) =&gt; { if (err) { return reject(err); } resolve(res); }])); }); } } // 将 `fs.readFile()` 转换为一个函数,该函数接受相同的参数但返回一个 Promise const readFile = util.promisify(fs.readFile); // 现在可以对 `readFile()` 使用 `await` 了! const buf = await readFile(&amp;#39;./package.json&amp;#39;); const obj = JSON.parse(buf.toString(&amp;#39;utf8&amp;#39;)); obj.name; // &amp;#39;masteringjs.io&amp;#39;</pre>どうやって理解すればいいでしょうか?まず、

util.promisify()

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

util.promisify()

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

Losing Context

関数の呼び出し時に内部の this 値が正しくないことを示します。コンテキストの喪失は、変換された関数の一般的な問題です。<pre class="brush:js;toolbar:false;">class MyClass { myCallbackFn(cb) { cb(null, this); } } const obj = new MyClass(); const promisified = require(&amp;#39;util&amp;#39;).promisify(obj.myCallbackFn); const context = await promisified(); context; // 打印 `undefined` 而非 `MyClass` 实例!</pre>

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

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

const obj = new MyClass();
// 保留上下文,因为 `promisified` 是 `obj` 的一个属性
obj.promisified = require(&#39;util&#39;).promisify(obj.myCallbackFn);

const context = await obj.promisified();
context === obj; // true
ノード関連の詳細については、

nodejs チュートリアル

を参照してください。

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

声明:
この記事はjuejin.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。