回调函数返回值的问题
发布于 8 年前 作者 huangyanxiong01 11306 次浏览 来自 问答
    ejs.ejs.filters.i8n = function (code, lang) {
        var _this = this;
        var langPath = path.normalize(consoleConfig.savePath + lang + '.' + consoleConfig.outputFileExt);
        fs.access(langPath, fs.R_OK, (err) => {
            if (err) throw err;
            fs.readFile(langPath, 'utf8', function (err, data) {
                var source = JSON.parse(data);
            });
        });

        //source 这里是假设,想将上面异步取回的数据在i8n这个函数中返回,能不能做到,怎么做
        return source;
    };

16 回复

简单说做不到 异步没法变同步 自豪地采用 CNodeJS ionic

没法这样搞,你外面得到的一定是undefined,你可以形参里传一个cb,通过cb把resource传出去,这样的话你调用这个函数时实例化这个cb就可以了,不过如果你不想回调套回调,你只能events模块发射事件,或者改写为promise,不知你能否理解(๑• . •๑)

@fantasticsoul 这里要做一个过滤器,不可能使用事件模块了

@huangyanxiong01 应该都是可以异步的,设计问题罢了,或者你可以先加载文件,放到模块变量,用的时候直接返回。fs也有同步的api

来自酷炫的 CNodeMD

异步代码不能return的,你那是同步的写法肯定不管用啊

@huangyanxiong01 可以使用事件模块,只是说你这里不涉及到复杂的处理流程,即多个异步逻辑汇总一个结果返回给上层业务逻辑,就没必要大动干戈了,所以这里最简单的做法就是形参里传一个回调,然后通过回调把resource传出去,那你外面调用filter时写个回调函数就拿到resource了,总之,你避不开回调的,除非你用fs模块的同步api,但是这样的话就有损性能了,同步意味着堵住真个线程,而node是单线程的,还有一种折中的方案就是改写成promise罗,用看似同步的代码写异步逻辑

@FoghostCn @fantasticsoul app.js

 const fs = require('co-fs');
app.use(function *(next) {
    this.session.lang = Object.isUndefined(this.session.lang) ? config.lang : this.session.lang;
    ejs.lang = JSON.parse(yield fs.readFile(path.normalize(consoleConfig.savePath + this.session.lang + '.' + consoleConfig.outputFileExt)));
    yield next;
});

template.js

module.exports = function (app) {
    i18n = function(key){
        console.info(msg);
      return "Hello "+msg;
    };

    ejs(app, {
        root: path.join(process.cwd(), 'view'),
        layout: false,
        //layout: 'template',
        viewExt: 'html',
        cache: false,
        debug: true,
        filters :{
            i18n : i18n
        }
    });
	
    /**
     * 语言过滤器
     * @param code
     * @param lang
     * @returns {*}
     */
   ejs.ejs.filters.i8n = function (code) {
        return ejs.ejs.lang[code];
    };
    return ejs.ejs;
};

@huangyanxiong01 这里还有些东西没有搞清楚,在koa的生成器中使用co-fs就像是同步代码一样,这是我不明白的地方

你要是做i18n的话项目启动的时候直接缓存到内存就行了,没必要每次去硬盘读

@huangyanxiong01 生成器的作用就是把异步跑的代码写来像同步的,但实际上是异步的,就是一种语法糖而已

@alsotang 这里有个黑科技,异步变同步~ https://github.com/abbr/deasync

@magicdawn 相对于这类黑科技。我觉得 yield 都还比较靠谱。。

@alsotang 提供一种可能吗~哈哈

@manxisuo

原理: 阻塞后面的js 执行, 知道异步的callback被调用, 然后将异步结果同步返回 代码上我也不太懂, 可以看看

回到顶部