首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >避免回调地狱

避免回调地狱
EN

Stack Overflow用户
提问于 2016-12-23 02:30:35
回答 3查看 356关注 0票数 0

我有这段代码,它服务于'./ markdown‘文件夹中的每个markdown文件。位于“/api/markdown/filename”。

代码语言:javascript
复制
var apiRouter = express.Router();

markdownFolder = './markdown/';

apiRouter.get('/:markdown_file_noext', function(req, res) {
        fs.readdir(markdownFolder, function(err, markdown) {
            if (err) throw err;
            markdown.forEach(function(file) {
            fs.readFile(markdownFolder + file, 'utf8', function(err, file_content) {
                if (err) throw err;
                fileNoExtension = file.slice(0, file.indexOf('.'));

                if (req.params.markdown_file_noext == fileNoExtension) {
                    res.json({ 
                        'title': fileNoExtension,
                        'markdown': marked(file_content)
                    });
                };
            });
        });
    });
});

但是我有一大堆的回调函数来做'fs‘方法的本质。我该如何避免这种情况?

EN

回答 3

Stack Overflow用户

发布于 2016-12-23 08:27:13

使用Q作为promise库:

代码语言:javascript
复制
const Q = require('q');
const fs = require('fs');

const markdownFolder = './markdown/';

const readdir = Q.nfbind(fs.readdir);
const readFile = Q.nfbind(fs.readFile);

readdir(markdownFolder).then(markdown => {
    const promises = [];
    markdown.forEach(file => promises.push(readFile(markdownFolder + file, 'utf8')));

    return Q.all(promises);
}).then(files => {
    // Do your magic.
}).catch(error => {
    // Do something with error.
});
票数 1
EN

Stack Overflow用户

发布于 2016-12-23 06:35:19

你有不同的选择。

  1. 使用命名函数而不是匿名函数。这将使它更具可读性,但您仍将使用回调。
  2. 使用Promises,但您将需要使用bluebird来包装fs模块。
  3. 对于更高级的选项,您可以使用生成器和Promises来使您的代码看起来更像是一种同步方式。看看cobluebird.coroutine.
票数 0
EN

Stack Overflow用户

发布于 2016-12-23 08:08:16

使用Promises,您可以这样做:

代码语言:javascript
复制
const path = require('path');
var apiRouter = express.Router();
markdownFolder = './markdown/';

apiRouter.get('/:markdown_file_noext', function(req, res) {
    readdir(markdownFolder)
    .then((files) => {
        const tasks = files.map((file) => {
            const filePath = path.resolve(markdownFolder, file);
            return readFile(filePath);
        });
        return Promise.all(tasks); // Read all files
    })
    .then((fileContents) => {
        return fileContents.map((content) => {
            fileNoExtension = file.slice(0, file.indexOf('.'));

            if (req.params.markdown_file_noext == fileNoExtension) {
                return { 
                    'title': fileNoExtension,
                    'markdown': marked(content)
                };
            };
        })        
    })
    .then((results) => {
        // It's better if you aggregate all results in one array and return it, 
        // instead of calling res.json for each result
        res.json(results);
    })
    .catch((err) => {
        // All errors are catched here
        console.log(err);
    })
});


function readdir(folderPath) {
    return new Promise((resolve, reject) => {
        fs.readdir(folderPath, (err, files) {
            if (err) {
                return reject(err);
            }

            resolve(files);
        });
    });
}

function readFile(filePath) {
    return new Promise((resolve, reject) => {
        fs.readFile(filePath, 'utf8', (err, file_content) => {
            if (err) {
                return reject(err);
            }            
            resolve(file_content);
        });
    });
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41289621

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档