2017-02-06 4 views
0

私はKoaフレームワークとES6を使用しています。 yieldが必要なこのビュー関数に結果を返す最初のメソッドを取得するにはどうすればよいですか?私はノード7.5アプリケーションで非同期呼び出しを使用するpgライブラリを使用しようとしています。非同期関数を呼び出すジェネレータからの結果を返すにはどうすればよいですか?

pgrepo.listCities = function*() { 
    pool.query('SELECT distinct(town) from public.property_uk', function(err, result) { 
    console.log("result: " + JSON.stringify(result.rows)); 
    // What now? 
    }); 
}; 

www.pgindex = function*() { 
    let results = yield pgrepo.listCities(); // What now? 

    console.log('handler: ' + results) 

    yield this.render('pgindex', { 
     items: results 
    }); 
} 

私は、yieldが実行を延期されて何が起こっているかを理解し、その機能が実行されていない結果と収穫した後、クエリの火災とは、結果を生成します。

私の質問は、どのようにこれらの2つの関数をリファクタリングして、クエリ結果がビューに渡す関数に返されるかです。

+0

ジェネレータが本当にありますか?最初の関数は何も返さず、2番目の関数は異なる型のデータを生成します。むしろ、非同期/待機を必要としているようです。 – zeroflagL

答えて

0

私はコア/ジェネレーターについては何も知らないので答えは考えていませんでしたが、簡単な約束でこれを取り除くことはできませんか? (他の誰も投稿していないので、少なくともあなたが解決できる方法をあなたに提供しようと思ったからです)

このコードはテストされていません。ここであなたはおそらくあなたの約束を作るあなたのコードのコルーチンバージョンが用されて探しているものをコード

// Since I have no idea why generators should be used here, let's remove the * 
// if you really do need it, then this answer might not work (as I said, I never 
// even touched generator functions, so I will just make this as arrow fn) 

pgrepo.listCities =() => { 
    // first let's return a promise to function call 
    return new Promise((resolve, reject) => { 
    pool.query('SELECT distinct(town) from public.property_uk', function(err, result) { 
     // since this is in callback, we can be sure that this will be executed 
     // when the query itself is finished. because this is a promise we 
     // can now here resolve it here with results. but first check for 
     // errors and reject if this query failed 
     if (err) { 
     reject(err); 
     } 
     resolve(result.rows); 
    }); 
    }); 
}; 

www.pgindex =() => { 
    // Since I have no idea why generators should be used here, let's remove the 
    // yield... 
    let results = pgrepo.listCities; 

    // now our results can call the listCities and get the promise 
    // back as result. as soon as that promise is resolved we can enter into .then 
    // and access values 

    results() 
    .then((results) => { 
     // this console log should now have all the results from the query. 
     console.log(results); 

     // you can now do here what you want with the data. again not sure how 
     // this can play with generators 

     // also this (both this as next commented block and this as pointer) will 
     // most likely fail due to arrow function changing context of this, so you 
     // might wanna play around with that to be sure you have correct context 
     // if it doesn't work out of the box. If you can't figure it you, you can 
     // change this arrow function in normal 'function (results) {...}' and your 
     // context will be fine and you will be able to call proper this (I think :)) 
     this.render('pgindex', { 
     items: results 
     }); 
    }) // and ofc error handling 
    .catch((err) => { 
     console.log('Something went wrong and I am terrible error message ' + err); 
    }); 
}; 
0

と少しより多くの自由を持っている場合と可能な解決策としての非同期を非表示にすることで、syncronousコードのように見えます自然。代わりに.then INGの約束、あなたがそれらを得て、次のようになり、あなたのコードを持つことができます。これは似ている

let co = require('co'); 
let pg = require('co-pg')(require('pg')); 

let connectionString = 'postgres://postgres:[email protected]/postgres'; 

co(function* connectExample() { 
    try { 
     let client = new pg.Client(connectionString); 
     yield client.connectPromise(); 

     let result = yield client.queryPromise('SELECT distinct(town) from public.property_uk'); 
     console.log(result); 

     client.end(); 
    } catch (ex) { 
     console.error(ex); 
    } 
}); 

への非同期/のawaitが、あなたは今日、それを使用することができます!それは何かを再発明する必要性がないとco

0

で使用することができますので、私はpgモジュールをpromisifiedました(執筆時点では、非同期/のawait非常にすぐにノードを入力しているが)

お知らせ、 pg-promiseは、箱から出してES6ジェネレータをサポートしています。すべての助けを

var pgp = require('pg-promise')(/*initialization options*/); 
var db = pgp(/*your connection details*/); 

function * getCities(t) { 
    var cities = yield t.query('SELECT distinct(town) from public.property_uk'); 

    // do whatever you need here 

    return cities; 
} 

function * Generator_Caller() { 
    try { 
     var cities = yield db.task(getCities); 
     console.log(cities); 
    } 
    catch (error) { 
     console.log(error); 
    } 
} 

function Regular_Caller() { 
    db.task(getCities) 
     .then(function (cities) { 
      console.log(cities); 
     }) 
     .catch(function (error) { 
      console.log(error); 
     }); 
} 
0

おかげで、私はそれが働いたと一緒に行った最終的なコードは次のとおりです。

pgrepo.listTowns = function*() { 
var results = yield pool.query('SELECT distinct(town) from public.property_uk'); 
return results; }; 

www.pgindex = function*() { 
const results = yield pgrepo.listTowns(); 

console.log("results: " + JSON.stringify(results.rows)); 

yield this.render('pgindex', { 
    items: results.rows 
});}; 
関連する問題