节点js

时间:2015-11-19 12:56:01

标签: javascript node.js asynchronous

我不熟悉节点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编写这个简单的函数。

2 个答案:

答案 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

相关问题