2017-02-06 5 views
0

Я использую структуру Koa и ES6. Как получить первый метод для возврата результата к этой функции представления, которая требует yield? Я пытаюсь использовать библиотеку pg, которая использует асинхронные вызовы, в приложении 7.5.Как вернуть результат генератора, вызывающего асинхронную функцию?

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

Вы действительно хотите генераторы? Первая функция ничего не дает, вторая дает разные типы данных. Кажется, вам скорее нужен async/wait. – 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

То, что вы, вероятно, ищете это версия сопрограмм вашего кода, которые делают ваши обещания выглядеть Синхронный код, скрывая свою асинхр природа. Вместо .then ИНГ обещания, вы можете дать им, и ваш код будет выглядеть следующим образом:

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, но вы можете использовать его сегодня! (Хотя на момент написания асинхронной/Await входит узел очень скоро)

Обратите внимание, что я promisified в pg модуль, поэтому он может быть использован с co

0

Без необходимости изобретать что-нибудь, 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 
});}; 
Смежные вопросы