私がそのコードを書いたわけではないので、以下は推測です。
実験としてその行を消すと、おそらく↓のテストが失敗するでしょう。
/test/parallel/test-util-promisify.js
ケースとしては以下が思いつきました。
- 別のコンテキストから得た関数を promisify するケース
class Foo extends Function
のインスタンスを promisify するケース
1. 別のコンテキストから得た関数を promisify するケース
vm.runInNewContext の結果として得られるオブジェクトは、vm.runInNewContext を実行しているのとは別のコンテキストで生成されたものになり、文字列にすると同じでも、instanceof の結果が異なります。
javascript
1const array1 = [1, 2, 3];
2console.log(array1);
3// → [1, 2, 3]
4
5const array2 = vm.runInNewContext('[1, 2, 3]');
6console.log(array2);
7// → [1, 2, 3]
8
9console.log([Array.isArray(array1), array1 instanceof Array]);
10// → [true, true]
11console.log([Array.isArray(array2), array2 instanceof Array]);
12// → [true, false]
ブラウザでも Web Worker や iframe を扱う時に注意が必要なポイントです。
参考文献:instanceof と複数のコンテキスト
setPrototypeOf により、別のコンテキストの関数を promisify した後の関数も、prototype としてその別のコンテキストの Function.prototype を持つことになります。
2. class Foo extends Function
のインスタンスを promisify するケース
javascript
1const util = require('util');
2
3class Foo extends Function {
4 constructor() {
5 super('callback', 'callback(null, 100)');
6 }
7 get bar() {
8 return 'bar';
9 }
10}
11
12function myPromisify(fn) {
13 return (...args) => new Promise((resolve, reject) => {
14 fn(...args, (error, value) => error ? reject(error) : resolve(value));
15 });
16}
17
18const foo = new Foo();
19const promisified1 = util.promisify(foo);
20const promisified2 = myPromisify(foo);
21console.log([promisified1.bar, promisified2.bar]);
22// → ['bar', undefined]
23console.log([promisified1 instanceof Foo, promisified2 instanceof Foo]);
24// → [true, false]
↑のように、Function を継承するクラス Foo のインスタンスを promisify する場合に、setPrototypeOf しないと、結果は Foo のインスタンスではなくなります。
まとめると、error-first callback style な関数を async な関数にする以外の副作用を起こさないようにする処置なのではないかと思いますが、いかがでしょうか。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2018/01/24 10:44
退会済みユーザー
2018/01/24 12:07
退会済みユーザー
2018/01/25 10:09
退会済みユーザー
2018/01/27 08:10 編集
退会済みユーザー
2018/01/25 11:16