web-dev-qa-db-ja.com

内部関数から譲ることはできますか?

ES6ジェネレーターでは、次のようなコードが表示されます。

var trivialGenerator = function *(array) {
    var i,item;
    for(var i=0; i < array.length; i++){
        item = array[i];
        yield item;
    };
};

代わりに以下のコードのようなものを書くことは可能ですか?

var trivialGenerator = function *(array) {
    array.forEach(function *(item){
        yield item;
    });
};

古典的なforループは嫌悪感があるので、私は尋ねています。

23
Max Heiber

いいえ、内部関数内では yield を使用できません。しかし、あなたの場合、あなたはそれを必要としません。 forEach メソッドの代わりに、常に for-of ループを使用できます。見栄えがよくなり、 continuebreakyield を使用できます=その中:

var trivialGenerator = function *(array) {
    for (var item of array) {
        // some item manipulation
        yield item;
    }
}

内部にアイテムの操作がある場合は、for-ofを使用できます。それ以外の場合、arrayにはネイティブの iterator interface があるため、このジェネレータを作成する必要はありません。

30
alexpods

いいえ、コールバックから譲ることはできません(技術的には、「内部関数」ではなく、別の意味です)。 forEach*と同等のもので呼び出す方法はありません。コールバック自体がジェネレータの場合は、forEachyield *でコールバックを呼び出すように指示する方法はありません。 。

1つの代替方法は、次のように関数forEachGenを記述することです。

function *forEachGen(array, fn) { for (var i of array) yield *fn(i); }

基本的にforループをforEachGenに移動します。小さなサンプルジェネレータを次のように定義する

function *yieldSelf(item) { yield item; }

forEachGenは次のように使用されます

yield *forEachGen(array, yieldSelf);

この例では、コールバックがジェネレータ自体であることを前提としています。コールバックがROF(通常の古い関数)の場合

function returnSelf(item) { return item; }

その後、それは

function *forEachGen(array, fn) { for (var i of array) yield fn(i); }

使用されます

yield *forEachGen(array, returnSelf);

これを配列プロトタイプに追加してもかまわない場合は、

Object.defineProperty(Array.prototype, 'forEachGen', { value :
    function *(fn) { for (i of this) yield fn(i); }
});

それから

yield *array.forEachGen(yieldSelf)

http://fitzgen.github.io/wu.js/ に興味があるかもしれません。これは、ラッパーにforEachなどのメソッドを持つジェネレーターのラッパーを定義します。

async/await

awaitを使用すると、次のことができるはずです。

それ自体のプロミスを返す単純なコールバックを定義します。

async function returnSelf(item) { return await item; }

forEachAsyncは、入力配列をpromiseの配列にマップし、await *を使用して、準備ができているすべての個々のpromiseのpromiseを作成して返します。

async function forEachAsync(values, fn) {
  return await *values.map(returnSelf);
}

結果を通常のプロミスとして扱い、thenに出力できます。

forEachAsync([1,2,3], returnSelf) .
  then(result => console.log(result);

または、小さなIIFE非同期ラッパーを使用して、結果を待機してから出力します。

(async function() { 
    console.log(await forEachAsync([1,2,3], returnSelf));
})();

を使用してテスト

babel-node --experimental test.js
4
user663031