您好我一直在使用名为deasync
的库,它允许我以更干净的方式完成工作,我有这样的方法,
syncGetMany: function(model, query){
var ret;
setTimeout(function(){
model.find(query, (error, body) => {
if(body){
//Awesome got the data
ret= body
}
else{
//What a cruel world
// No data, fall back to an empty array
ret = [];
}
});
},0);
while(ret === undefined) {
require('deasync').sleep(0);
}
//returns an empty array or the real data
return ret;
},
然后我就这样称呼它。
var data = syncGetMany(MongooseModel, queryObj);
// the rest of my code
问题:有没有办法使用ES6或任何类似的库完成此操作。
PS:不重复,因为其他问题与我的背景无关
答案 0 :(得分:1)
使这段代码更清晰的最简单方法是使用async / await,它可以在node.js中获得版本=> 7.0。如果我认为你的model.find方法会返回promise。
async syncGetMany (model, query) {
let ret;
ret = await model.find(query);
//ret is keeping body from response now, if error occured error is throwed as promise exception
//Could do some sync ops on ret variable
return ret;
}
当你使用async / await时,你应该把你的方法执行放到try / catch中。但是你也可以在syncGetMany方法中捕获错误,可能它应该是这样的:
async syncGetMany(model, query) {
let ret;
try {
ret = await model.find(query);
return ret;
} catch(err) {
console.error(err);
return []; //empty array or any error string/object
}
}
你的执行看起来像是用额外的await运算符编写的(使用es6为var运算符替换提供let / const运算符)
let data = await syncGetMany(MongooseModel, queryObj);
有异步/等待解释的文章: https://blog.risingstack.com/async-await-node-js-7-nightly/
如果您不想使用Node v7.0,您应该使用promises和generator编写类似的代码。
https://medium.com/@rdsubhas/es6-from-callbacks-to-promises-to-generators-87f1c0cd8f2e
我希望我能帮忙。
<强>更新强> 因此,当您的mongoose实例不支持promise时,有三个选项(取决于我对节点版本的看法)。在我看来,promises是更简洁的异步请求方式所以我建议使用它们。
第一个选项(原生承诺):
syncGetMany(model, query) {
return new Promise((resolve, reject) => {
model.find(query, (err, res) => {
if(err) {
return reject(err);
}
resolve(res);
});
});
}
第二个选项(bluebird库,为所有方法添加了Async postfix):
const mongoose = require( 'mongoose' );
const Promise = require('bluebird');
Promise.promisifyAll( mongoose );
async syncGetMany(model, query) {
let ret;
try {
ret = await model.findAsync(query);
return ret;
} catch(err) {
console.error(err);
return []; //empty array or any error string/object
}
}
第三个选项(节点版本=&gt; 8.0):
在功能上使用原生promisify: https://nodejs.org/dist/latest-v8.x/docs/api/util.html#util_util_promisify_original
在我们的同步部分(在函数构造之前使用异步运算符):
let data = await syncGetMany(MongooseModel, queryObj);
答案 1 :(得分:-1)
您可以使用nsynjs编写和执行逻辑,就好像它是同步的一样:
function synhronousCode(model, query) {
function syncGetMany(model, query){
return model.find(query).data; // data will contain result of resolved promise at this point
};
var data = syncGetMany(model, query);
// do stuff with data
}
var nsynjs = require('nsynjs');
....
nsynjs.run(synhronousCode,{},model, query, function(){
console.log('synhronousCode done');
});
nsynjs将以顺序方式评估synhronousCode
中的代码:如果某个函数返回promise(如model.find
那样),nsynjs将暂停执行并等待promise被解析,并将结果赋给{{1}返回值的属性,然后继续执行。