蓝鸟承诺未定义?

Posted

技术标签:

【中文标题】蓝鸟承诺未定义?【英文标题】:Bluebird promise is undefined? 【发布时间】:2017-01-19 16:11:32 【问题描述】:

我正在使用节点 4.5+ 和蓝鸟。我有以下代码打算与then一起使用:

var checkdir = function(directory) 
    return new Promise(function(resolve, reject) 
        fs.statAsync(directory).then(function() 
            resolve(true);
        ).catch(function(err) 
            if(err.code === 'ENOENT') 
                fs.mkdirAsync(directory).then(function() 
                    resolve(true);
                ).catch(function() 
                    reject(new Error('Can not create folder'));
                );
             else 
                reject(new Error('Unknown fs stat error: ' + err));
            
        );
    );
;

Async 函数来自fs-extra-promise 模块。但是,当我尝试使用此功能时,我得到Unhandled rejection Error: Unknown error: TypeError: Cannot read property 'then' of undefined

调用:

                checkdir(dir).then(function() 
                    ...
                ).catch(function(err) 
                    reject(new Error('Unknown error: ' + err));
                );

这里有什么问题?

【问题讨论】:

这很奇怪,您的代码在没有蓝鸟的 sn-p 中运行。你如何实现这个库? 见***.com/questions/23803743/… 错误所指.then 的任何指示(堆栈跟踪)? @Tomalak 不确定您的意思,但请随时编辑和修复它。 【参考方案1】:

在文件系统操作中使用任何类型的“存在”检查是节点文档中的actively discouraged。 (您是否使用statexists 进行存在检查是无关紧要的。)

这意味着,除了 Benjamin Gruenbaum 在您的代码中对 the improper use of promises in general 的评论之外,还有另一个重要的观点:

创建目录的正确方法是无条件调用mkdir 并忽略EEXIST(比较this answer 了解更多上下文)。

var fs = Promise.promisifyAll(fs);

var ensureDir = function ensureDir(path) 
    return fs.mkdirAsync(path).catch((err) =>  if (err.code !== 'EEXIST') throw err; );

您可以使用the mkdirp module 递归地创建路径,就像mkdir -p 那样。

【讨论】:

我更改了代码,但仍然出现错误:Unhandled rejection Error: Unknown error: TypeError: Cannot read property 'then' of undefined。会不会是另一个承诺被拒绝? 我的代码中没有.then(),所以你看到的错误与它无关。 我有另一个承诺会破坏整个链的返回结果。谢谢!

以上是关于蓝鸟承诺未定义?的主要内容,如果未能解决你的问题,请参考以下文章

错误:`未捕获(承诺中)类型错误:无法读取未定义的属性'doc'`

可能未处理的承诺拒绝未定义不是一个函数

VueJS:未捕获(承诺中)TypeError:无法读取未定义的属性“推送”

Vue:未捕获(承诺中)TypeError:无法读取未定义的属性'_c'

未捕获(承诺)TypeError:无法读取未定义的属性“长度”

未处理的承诺拒绝:未定义不是对象(评估 _expoLocation.requestForegroundPermissionsAsync)