javascript bluebird Promise -> 从异步列表中获取第一个文件

标签 javascript recursion promise mocha.js bluebird

我尝试使用 JavaScript 的 Promise 从路径列表中获取第一个路径(即 ["c:\\temp\\test1.json", "c:\\temp\\test2.json"])光盘上可用的文件(即 c:\temp\test2.json)。

function getFirstFile(paths) {

    if (!paths || paths.length == 0) {
        return {};
    }

    // sequential async search (recursive)
    var filePath = paths.shift();
    return fs.readFileAsync(filePath)
        // found = stop searching
        .then(function (content) {
            return new Promise (function (resolve, reject) {
                resolve(JSON.parse(content));
            })
        })
       // continue searching further paths left in the list
       .error(function (err) {
            return getFirstFile(paths);
       });
 }    

var paths2 = ["c:\\temp\\test1.json", "c:\\temp\\test2.json"];

getFirstFile(paths2)
    .then( function (index) {
        assert.equal(index.file, ".test2.json");
    })
    .error( function(err) {
        assert.fail(err.toString());
    });

由于某种原因,尽管文件“C:\temp\test2.json”可用,但 fs.readFileAsync(filePath) 未进入 .then(function (content) {

...就像 Promise 有异常或者没有捕获到什么?

最佳答案

为了清楚起见 -> 下面的代码无需 Mocha 测试即可正常工作。当集成到 Mocha 中时,无论我有 test2.json 做什么,测试都会顺利通过。

var fs = require('fs');
var Promise = require('bluebird');  //much faster than Chrome native promises
if (typeof fs.readFileAsync === "undefined") {Promise.promisifyAll(fs);}  // generate Async methods from callbacks
var path = require('path');

function getFirstFile(paths) {

    if (!paths || paths.length == 0) {
        return {};
    }
    // sequential async search (recursive)
    var filePath = paths.shift();
    return fs.readFileAsync(filePath)
        // found = stop searching
        .then(function (content) {
            return new Promise (function (resolve, reject) {
                resolve(JSON.parse(content));
            })
        })
        // continue searching further paths left in the list
        .error(function (err) {
            return getFirstFile(paths);
        })
        .catch(function (e) {
            return getFirstFile(paths);
        });
}

var paths2 = ["c:\\temp\\test1.json", "c:\\temp\\test2.json"];

getFirstFile(paths2)
.then( function (index) {
    console.log(JSON.stringify(index));
})
.error( function(err) {
    console.log(err);
});

错误在于 Mocha 测试的调用方式(请参阅错误和良好的测试代码)。

错误的代码(Mocha 总是会通过,因为 promise 在测试后返回):

it('My Test', function () {    
    utils.getFirstFile(["c:\\temp\\test1.json", "c:\\temp\\test2.json"])
    .then(function(index) {
        assert.equal(index.file, ".test2.json");
    })
    .catch( ....);
}

正确的代码是(返回 promise ):

it('My Test', function () {    
    return utils.getFirstFile(["c:\\temp\\test1.json", "c:\\temp\\test2.json"])
        .then(function(index) {
             assert.equal(index.file, ".test2.json");
        });
}

关于javascript bluebird Promise -> 从异步列表中获取第一个文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32681305/

相关文章:

r - 如何有效地可视化递归函数?

正确的括号

javascript - 使用 Dexie 和 Svelte 从 IndexedDB 中检索值

javascript - 向上/向下移动时在窗口中保留所选选项

javascript - 告诉浏览器的 Javascript 版本

scala - 如何在 Scala 中对列表中的两个邻居求和

javascript - 如何避免从 promise 中提取解析,同时在回调之前启动流程?

javascript - 在后面的链链接中使用第一个 promise 的值(value)

javascript - 如果对象未定义,为什么 "if ( ! Object.property)"会中断?

javascript - 在特定背景颜色上创建菜单标题导致对齐出错