Javascript承诺链接 - 奇怪的行为

时间:2016-12-08 17:20:32

标签: javascript es6-promise

我正在使用此代码进行测试:

.eslintrc.json 528
.git 4096
.gitignore 26
README 0
callbacks.js 1402
functions-1.js 530
functions-2.js 564
functions-3.js 1798
functions-4.js 737
functions-5.js 1045
All files size is:  10726

我使用节点v 6.9.1运行它,结果是:

.eslintrc.json 528
.git 4096
.gitignore 26
README 0
functions-1.js 530
callbacks.js 1402
functions-2.js 564
functions-3.js 1798
functions-5.js 1045
All files size is:  9989
functions-4.js 737

到目前为止,这么好。但有时候,我得到的可能是10分之一:

{{1}}

注意有时在实际循环结束之前执行最终结果。为什么?我不能自己解决这个问题,我需要帮助才能意识到造成这个错误的原因。

P.S。底部的文件不是函数-4.js总是。

请帮忙

3 个答案:

答案 0 :(得分:3)

如果您只想在文件的所有计算完成时解决,那么您应该在函数calculateSize(files)中使用Promise#all

function calculateSize(files) {
    return Promise.all(files.map(function (file) {
        return getFullPath(file).then(getFileSize).then(function(size) {
                console.log(file, size)
                return size
            })
        })
    }).then(function (sizes) {
        return sizes.reduce(function (a, b) {
            return a + b
        })
    })
}

您甚至可以通过删除最终的then回调,将函数映射到一个大小数组的数组。

答案 1 :(得分:1)

我建议不要滚动你自己的宣传,这很乏味且容易出错。让像bluebird这样的图书馆为你做这件事。

与bluebird提供的其他功能一起,例如.map().reduce()的实现,您的代码可以像这样简单直接地制作:

var Promise = require('bluebird');
var path = require('path');
var fs = Promise.promisifyAll(require('fs'));

function calculateSizeAsync(dir) {
    return fs.readdirAsync(dir)
        .map(file => path.join(dir, file))
        .map(filepath => fs.statAsync(filepath))
        .reduce((total, stats) => {return total + stats.size}, 0);
}

calculateSizeAsync('/home/galio/DEV/js-sandbox')
    .then(totalSize => console.log('All files size is: ' + totalSize))
    .catch(err => console.error('ERROR:', err));

答案 2 :(得分:0)

我认为你的第二个then并不等待calculateSize()。

试试这个

getFiles('/home/galio/DEV/js-sandbox').then(function(result){
  calculateSize(result).then(function(size){
    console.log('All files size is: ', size);
  }
}, 
function(err){ console.log('ERROR:', err); }
);