Javascript蓝鸟承诺->从异步列表中获取第一个文件

javascript bluebird promise -> get first file from list async

本文关键字:列表 异步 获取 文件 第一个 承诺 蓝鸟 Javascript      更新时间:2023-09-26

我试图使用javascript从路径列表(即["c:''temp''test1。c:'temp'test2.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. C "fs.readFileAsync(filePath)没有输入.then(function (content) {

…这就像承诺有一个例外或其他没有被捕获的东西?

为了清楚起见->下面的代码没有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( ....);
}

正确的代码是(返回一个承诺):

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

是的,很可能承诺最终拒绝(JSON)。解析可能抛出了一个导致拒绝的错误),但是因为

   .error(function (err) {
        return getFirstFile(paths);
   });

拒绝将被捕获,函数将反复运行。它将永远在一个循环中运行,永远不会真正达到拒绝。你需要让承诺被拒绝

.error()方法"只捕获操作错误",来自JSON.parse的异常不会被捕获。你应该使用.catch()方法——至少在调用assert.fail的最终处理程序中。

function getFirstFile(paths) {
    if (!paths || paths.length == 0) return {};
    // sequential async search (recursive)
    var filePath = paths.shift();
    return fs.readFileAsync(filePath)
    .then(JSON.parse)
    .catch(function (err) {
        return getFirstFile(paths);
    });
}
getFirstFile(["c:''temp''test1.json", "c:''temp''test2.json"])
.then(function(index) {
    assert.equal(index.file, ".test2.json");
})
.catch(function(err) {
    assert.fail(err.toString());
});