2017-06-16 1 views
2

私はオブジェクトジェネレータの使い方を学び、yieldコマンドを使ってnodejsコントローラでいくつかの同期操作を実行しようとしています。オブジェクトジェネレータ関数は、実行してはならない結果を返しません。

FOOコールを最初に実行し、戻ったときにBARコールを実行します。

私は

Hello FOO 
Hello BAR 

を表示するには、コンソールを期待していた。しかし、私が得るすべては私も関数内console.logsを得るいけない

Result [object Generator] 
Result [object Generator] 

である。この場合、

var myResult = findUser1("FOO") 
    console.log("Result " + myResult) 

    myResult = findUser1("BAR") 
    console.log("Result " + myResult) 

function* findUser1(UID) { 
    var user1 = yield setTimeout("Hello " + UID, 2000); 
    console.log("This should be shown AFTER user1 has a result"); 
    console.log(user1); 
    return user1; 
} 

答えて

2

私はあなたがpromisesを探していると思いますが、ジェネレータ機能はありません。ジェネレータ関数は、IterableIteratorオブジェクトを返します。これらのオブジェクトはiterator protocolに準拠しています。つまり、valueフィールドとdoneブールフィールドを持つオブジェクトを返すnext()メソッドを持っています。また、iterable protocolに準拠しています。つまり、イテレータオブジェクトを返す特別な@@iteratorメソッドを持っています(この場合は、それ自身のイテレータであるため、自身を返します)。

約束事は、まだ存在しないが将来のある時点で存在する可能性がある値を表します。また、awaitというキーワードを使って約束を使うことを簡素化するasync functionsも提供しています。ここにあなたのコードは、非同期機能を使用して見えるかもしれません方法は次のとおりです。

async function findUser(id) { 
    const user = await new Promise((resolve, reject) => { 
    setTimeout(() => resolve("Hello " + id), 2000); 
    }); 
    console.log("This should be shown AFTER user has a result"); 
    console.log(user); 
    return user; 
} 

async function getUsers() { 
    const user1 = await findUser("FOO"); 
    console.log("Result " + user1); 
    const user2 = await findUser("BAR"); 
    console.log("Result " + user2); 
} 

getUsers(); 

あなたはasync/await構文を使用したくない場合は、次のように等価です:答えのための

function findUser(id) { 
    return new Promise((resolve, reject) => { 
    setTimeout(() => resolve("Hello " + id), 2000); 
    }).then((user) => { 
    console.log("This should be shown AFTER user has a result"); 
    console.log(user); 
    return user; 
    }); 
} 

findUser("FOO") 
    .then(user1 => console.log("Result " + user1)) 
    .then(() => findUser("BAR")) 
    .then(user2 => console.log("Result " + user2)); 
+0

Waou !!!私は、「非同期関数」があることを知っていませんでした - あなたの例をすぐに試してみましょう! – torbenrudgaard

+0

私は奇妙なエラーが発生します: '非同期関数findUser(id){'と 'SyntaxError:予期しないトークン関数'は役に立ちますか? – torbenrudgaard

+0

@torbenrudgaardどのNodeのバージョンを使用していますか?このコードの両方のバージョンは、Chromeの最新バージョンのコンソールにコピーして貼り付けると機能します。ノードの非同期機能(および非同期ジェネレータ機能)の現代バージョン – sbking

1

まず、ジェネレータのチュートリアルを確認する必要があります。

var findUser = findUser("FOO"); 
var myResult = findUser.next().value; 
console.log("Result " + myResult); 
findUser.next(); 


function* findUser1(UID) { 
    var user1 = yield setTimeout(() => {"Hello " + UID}, 2000); 
    console.log("This should be shown AFTER user1 has a result"); 
    console.log(user1); 
    return user1; 
} 

はあなたがsetTimeout関数の最初の引数としてコールバック関数を渡す必要があり、次の機能のあなたの戻り値があることに注意してください:発電機を使用するためには、まず、それはので、あなたのコードは次のようになる使用ジェネレータを作成する必要がありますフォームを持つオブジェクト:

{ 
    value: ..., 
    done: false 
} 

と、アプリケーション内には、あなたの関数を完了するためにあなたが再びnext()を呼び出す必要があり、タイムアウト関数から返されたオブジェクトです。 ジェネレータのyieldコマンドが返されたものがnext()に返されることに注意してください。

function asyncFlow(generatorFunction) { 
    function callback(err) { 
    if (err) { 
     return generator.throw(err); 
    } 
    const results = [].slice.call(arguments, 1); 
    generator.next(results.length > 1 ? results : results[0]); 
    } 
    const generator = generatorFunction(callback); 
    generator.next(); 
} 

asyncFlow(function* (callback) { 
    console.log('1. Hello'); 
    yield setTimeout(callback, 2000); 
    console.log('2. 2000ms'); 
    yield setTimeout(callback, 1000); 
    console.log('3. 1000ms'); 
}); 

coは、あなたがその詳細hereを見つけることができ、発電機ベースの制御フローのための良いライブラリです:終わり

はのは、発電機と制御フローを作成する上でいくつかの方法を見てみましょう。

ジェネレータの横に、ネイティブjsまたはasyncのECMA2017機能を使用して、制御フローを管理できます。

+0

こんにちはパラム、感謝。私は実際にいくつかのチュートリアルを試しましたが、多くの人が説明しているように動作しませんが、他の人は本当に理解しにくいです。だから最初にジェネレータを作成しなければならない、私は今それを試します。 – torbenrudgaard

+0

私はより多くの助けに私の答えで詳細を追加しようとすると、ジェネレータとnodejsの同期のような機能を作成したいですか? –

+0

私がする必要があることは、彼が存在していれば、ある人を見つけて、他のユーザーを見つけることです。私は約束を試みましたが、あまりにも乱雑になります。私はあなたの例を試して3行を取得しました: 'Result [object Object]'と ' これは、user1が結果と'undefined'の後に表示されるはずです – torbenrudgaard

関連する問題