node.js - 如何从函数返回fs.lstat方法的结果

标签 node.js asynchronous fs

我尝试检查给定的路径是文件夹还是文件。我必须异步执行此操作,并将结果显示在pug文件中,而不是在控制台上。

const fs = require("fs");
module.exports = function (path) {
fs.lstat(path, (err, stats) => {
    if(err)
        return console.log(err);
    if (stats.isFile())
        return(`Is file: ${stats.isFile()}`);
    if (stats.isDirectory())
        return(`Is directory: ${stats.isDirectory()}`);
}); 


}

最佳答案

呈现回调到哈巴狗布局的3种方法

有两种方法可从异步函数返回值,即回调或诺言,
但说实话,如果您只使用一次通话就不会
与在路由中内联对fs.lstat的调用完全不同,因此我将提供
作为第三种选择。

示例的目录结构

如果您想遵循此步骤,则此示例为目录结构。

.
├── app.js
├── stat.js
└── views
    └── index.pug

1 directory, 3 files


安装依赖

您需要在此示例中安装express和pug

npm install pug express


布局示例

首先,这是一个示例布局./views/index.pug,我们将用于演示:

html
    head
        //- This title comes from the express res.render 
        title= title
    body
        //- This title comes from the express res.render 
        h1= title
        //- This message comes from the express res.render 
        p= statResult


示例1:回调

这是使用回调的可能的目录/文件报告功能。回调
基本上就是您已经发送到这里的fs.lstat
通过包装仅对其输出进行简单更改的地方
它在我们自己的名为cb的节点样式回调中。节点样式回调
通常有两个参数,错误是第一个参数,数据是第二个参数。
我们将遵循节点样式的回调模式。用我们自己的回调包装fs.lstat
允许函数仅调用我们的函数
获取我们想要的返回值,而不是所有信息
fs.lstat可能提供其他方式。

出于示例目的,我们将此功能放在名为stat.js的文件中。
除非您知道如何处理stat.js中的错误
最好通过回调传递错误,以防
调用函数可以更好地处理错误。
重要的是不要吞下/丢失Node中的错误。

// stat.js
const fs = require("fs");
module.exports = function (path, cb) {
    fs.lstat(path, (err, stats) => {
        if (err)
            return cb(err);
        if (stats.isFile())
            return cb(null, `Is file: ${stats.isFile()}`);
        if (stats.isDirectory())
            return cb(null, `Is directory: ${stats.isDirectory()}`);
    });
}


回调函数的用法

这是一个简单的快速应用程序如何使用此回调。好
出于示例目的,将其放在名为app.js的脚本文件中。
注意我们如何将“视图引擎”设置为“ pug”,
在我们的views目录中res.render'index.pug'。

// app.js
const express = require('express');
const app = express();
const stat = require('./stat.js');
const port = 3020;

app.set('view engine', 'pug');

app.get('/views', function (req, res) {
    stat("./views", (err, statResult) => {
        if (err) {
            res.render("Oops something went wrong!");
            console.error(err);
        }
        res.render('index', {
            title: "Views Directory Stat Result",
            statResult: statResult
        })
    })
})

app.get('/', function (req, res) {
    stat("./app.js", (err, statResult) => {
        if (err) {
            res.render("Oops something went wrong!");
            console.error(err);
        }
        res.render('index', {
            title: "App.js Stat Result",
            statResult: statResult
        })
    });
})


app.listen(port, function () {
    console.log("app listening on http://localhost:" + port)
})


示例2:承诺

Promises
如果您了解异步代码,它是一个非常方便的异步代码工具
他们足够好,他们可以在错误处理方面取得巨大的进步。

这是您使用诺言的自定义统计示例代码。注意如何
返回新构建的承诺,这很重要,因为
承诺是代表最有可能出现的价值的价值
将来的某个时间。承诺构造函数为您提供
解决和拒绝功能。这是因为一个承诺可以存在于任何
三种状态之一,“待定”表示尚未确定其状态
或“已解决”或“已拒绝”。拒绝有错误的承诺是一种
就像在同步代码中引发错误一样。这是我们以前的stat.js的替代品
文件。

// stat.js
const fs = require("fs");
module.exports = function (path) {
    return new Promise((resolve, reject) => {
        fs.lstat(path, (err, stats) => {
            if (err)
                return reject(err);
            if (stats.isFile())
                return resolve(`Is file: ${stats.isFile()}`);
            if (stats.isDirectory())
                return resolve(`Is directory: ${stats.isDirectory()}`);
        });
    })
}


以下是在简单应用程序中如何使用该stat.js文件的方法。
需要注意的一件事是,您必须将.then链接起来以保证获得
如果解决了它们,并且您想抓住任何被拒绝的诺言,那么它们中的价值
 您需要使用.catch来捕获它们。就像同步代码一样,当您发现错误时
除非您重新抛出错误,否则就假定您已经处理了错误。
关于诺言有很多事情要知道,我不会涵盖所有内容
简洁起见,但我将在底部链接一些文章,您可以了解更多信息。

尽管链接的替代方法是使用异步/等待
在该函数之前的关键字async使用该函数
关键字,可让您将await Promise值用作同步值。
您可以认为await就是将价值分解为承诺。以下是代码
诺言实现中的新app.js,其中路由/views执行链接api
并路由/做async / await api:

// app.js
const express = require('express');
const app = express();
const stat = require('./stat2.js');
const port = 3020;

app.set('view engine', 'pug');

app.get('/views', function (req, res) {
    stat("./views").then(statResult => {
        res.render('index', {
            title: "Views Directory Stat Result",
            statResult: statResult
        })
    }).catch(function (err) {
        res.render("Oops something went wrong!");
        console.error(err);
    })
})

app.get('/', async function (req, res) {
    try {
        const statResult = await stat("./app.js");
        res.render('index', {
            title: "App.js Stat Result",
            statResult: statResult
        })
    } catch (err) {
        res.render("Oops something went wrong!");
        console.error(err);
    }
})


app.listen(port, function () {
    console.log("app listening on http://localhost:" + port)
})


示例3:内联到lstat的调用

如果您不想重复自己,这可能不是您想要做的,
但是,始终可以将您的呼叫内联到lstat。因此,您只会
有一个app.js文件,它看起来像这样:

// app.js
const express = require('express');
const app = express();
const fs = require('fs');
const port = 3020;

app.set('view engine', 'pug');

app.get('/views', function (req, res) {
    fs.lstat("./views", (err, stats) => {
        if (err) {
            res.render("Oops something went wrong!");
            console.error(err);
        }
        let statResult = "";
        if (stats.isFile())
            statResult = `Is file: ${stats.isFile()}`;
        if (stats.isDirectory())
            statResult = `Is directory: ${stats.isDirectory()}`;
        res.render('index', {
            title: "Views Directory Stat Result",
            statResult: statResult
        })
    });
})

app.get('/', function (req, res) {
    fs.lstat("./app.js", (err, stats) => {
        if (err) {
            res.render("Oops something went wrong!");
            console.error(err);
        }
        let statResult = "";
        if (stats.isFile())
            statResult = `Is file: ${stats.isFile()}`;
        if (stats.isDirectory())
            statResult = `Is directory: ${stats.isDirectory()}`;
        res.render('index', {
            title: "App.js Stat Result",
            statResult: statResult
        })
    });
})


app.listen(port, function () {
    console.log("app listening on http://localhost:" + port)
})


好吧,这是返回异步值的仅有三种方法
在哈巴狗中呈现。希望有帮助,随时问我
您在注释中对此代码有任何疑问。
老实说,我建议兑现承诺
被调用时只有一个返回值。

以下是关于诺言的一些参考:

MDN's Using Promises

Jake Archibald's JavaScript Promises: an Introduction

关于node.js - 如何从函数返回fs.lstat方法的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58758437/

相关文章:

javascript - if else 内循环

c++ - 使用use_future的多播Boost Asio async_recieve_与async_send_to不能同时使用

javascript - FS 覆盖文件

node.js - 在 Node 中模拟 postgres 调用

node.js - Npm安装在Docker容器中找不到我的自定义注册表

javascript - 如何通过变量将数据插入MySQL数据库?

javascript - 当出现异步超时错误时,如何使用 jest 测试 Express 应用程序?

xcode - 在后台加载 gif 图像?

node.js - 如何使用 Node.js 创建带缓冲区的读取流

javascript - 如何在 Electron 中将 ImageData 保存为 PNG