我不熟悉节点js中的异步编程,并想知道如何将我以前的(同步)编程转换为节点js中的可读异步编程。特别是这个例子:
function getDefaultValue1() {
return getDefaultValue1FromDB();
};
function getDefaultValue2() {
return getDefaultValue2FromDB();
};
function doSomething(var optionalValue1, var optionalValue2){
try {
if(optionalValue1===null){
optionalValue1 = getDefaultValue1();
}
if(optionalValue2===null){
optionalValue2 = getDefaultValue2();
}
var resultList = [];
for(var i = 0; i < optionalValue2; i++) {
resultList.push(functionWithDbCall(optionalValue1, i));
}
return doSomeCalculations(resultList);
}catch(var e){
//log exception
return null
}
};
请注意,所有DB-Calls在节点js中都是异步的(getDefaultValue1FromDB(var callback),functionWithDbCall(var optionalValue1,var i,var callback))。
我的想法是: 将callback-parameter添加到getDefaultValue =&gt;在回调和if之后需要相同的代码。对于在调用回调之前的循环退出,并且回调需要处理它们被调用的频率并检查以正确的顺序推送项目。将函数更改为使用异步方法需要在调用它的任何地方更改代码,例如将getDefaultValue更改为将const int返回到DB调用。
我被困在这里,所有我发现广告的某些库或不可读的代码更糟糕的asm或正则表达式(一次写入,再次读取/触摸)。我是否遗漏了我的节点js学习资料中的基本内容,或者这是该语言的设计失败?
所以我希望有人可以告诉我如何用async node js编写这个简单的函数。
答案 0 :(得分:1)
我建议使用Bluebird:
var Promise = require('bluebird');
/**
* Lets assume getDefaultValue1FromDB() passes a callback fn;
* @return {Promise}
*/
function getDefaultValue1() {
return new Promise(function(resolve, reject){
return getDefaultValue1FromDB(function(err, value){
if (err) return reject(err);
return resolve(value);
});
});
}
/**
* Lets assume getDefaultValue2FromDB() passes a callback fn;
* @return {Promise}
*/
function getDefaultValue2() {
return new Promise(function(resolve, reject){
return getDefaultValue2FromDB(function(err, value){
if (err) return reject(err);
return resolve(value);
});
});
}
/**
* @param {Promise|int} optionalValue1
* @param {Prommise|int} optionalValue2
* @return {Promise}
*/
function doSomething(optionalValue1, optionalValue2){
if(optionalValue1 === null)
optionalValue1 = getDefaultValue1;
if(optionalValue2 === null)
optionalValue2 = getDefaultValue2;
return Promise
.all([optionalValue1, optionalValue2])
.spread(function(val1, val2){
var resultList = [];
for(var i = 0; i < val2; i++) {
resultList.push(functionWithDbCall(val1, i));
}
return doSomeCalculationsAsync(resultList);
}).catch(function(err){
//Log any errors here.
});
}
/**
* Calls the db and returns a promise with the result.
* @return {Promise} [description]
*/
function functionWithDbCall(val, i) {
Return new Promise();
}
/**
* @param {[Promise]} list Array of promises.
* @return {Promise}
*/
function doSomeCalculationsAsync(list) {
return Promise.all(list).then(doSomeCalculations);
}
请注意,doSomething
会返回一个承诺,因此您必须添加.then()
来处理结果。同样假设functionWithDbCall
也返回一个Promise,然后你可以将所有这些放在Promise.all()
中,然后进行计算。
答案 1 :(得分:1)
您可能希望使用ES7提案中的async/await - 未来版本的JavaScript。请参阅this answer,了解如何从回调迁移到承诺到异步/等待。
要今天实际运行未来的代码,您需要使用Babel将其编译为当前支持的功能。此外,它可以比异步/等待做a lot more。