美文网首页
Node.JS中如何判断递归嵌套的所有回调函数已经执行完毕,以读

Node.JS中如何判断递归嵌套的所有回调函数已经执行完毕,以读

作者: 流动码文 | 来源:发表于2018-04-24 19:43 被阅读31次

Promise 方法

Promise有一个 all 方法:

var fs        = require('fs');
var readdir   = promisify(fs.readdir);
var stat      = promisify(fs.stat);
var readFile  = promisify(fs.readFile);

// 简单实现一个promisify
function promisify(fn) {
  return function() {
    var args = arguments;
    return new Promise(function(resolve, reject) {
      [].push.call(args, function(err, result) {
        if(err) {
          console.log(err)
          reject(err);
        }else {
          resolve(result);
        }
      });
      fn.apply(null, args);
    });
  }
}

function readDirRecur(file, callback) {
  return readdir(file).then((files) => {
    files = files.map((item) => {
      var fullPath = file + '/' + item;

      return stat(fullPath).then((stats) => {
          if (stats.isDirectory()) {
              return readDirRecur(fullPath, callback);
          } else {
            /*not use ignore files*/
            if(item[0] == '.'){
              //console.log(item + ' is a hide file.');
            } else {
              callback && callback(fullPath)
            }
          }
        })
    });
    return Promise.all(files);
  });
}

var fileList = []

var timeStart = new Date()

readDirRecur('D:/github/oncedoc', function(filePath) {
  fileList.push(filePath)
}).then(function() {
  console.log('done', new Date() - timeStart);
  console.log(fileList);
}).catch(function(err) {
  console.log(err);
});

计数方法:

计数是比较常用的一种方法,其原理类似于c/c++中的引用计数,实现起来比较容易:

var fs        = require('fs');

function readDirRecur(folder, callback) {
  fs.readdir(folder, function(err, files) {
    var count = 0
    var checkEnd = function() {
      ++count == files.length && callback()
    }

    files.forEach(function(file) {
      var fullPath = folder + '/' + file;

      fs.stat(fullPath, function(err, stats) {
        if (stats.isDirectory()) {
            return readDirRecur(fullPath, checkEnd);
        } else {
          /*not use ignore files*/
          if(file[0] == '.') {

          } else {
            fileList.push(fullPath)            
          }
          checkEnd()
        }
      })
    })

    //为空时直接回调
    files.length === 0 && callback()
  })
}

var fileList  = []
var timeStart = new Date()

readDirRecur('D:/github/oncedoc', function(filePath) {
  console.log('done', new Date() - timeStart);
  console.log(fileList);
})

测试结果比较:
Promise法,耗时 6.2 秒 左右

$ node test.promise.js
done 6214
[ ...
  ... 55621 more items ]

计数法,耗时 3.5秒左右

$ node test.count.js
done 3590
[ ...
  ... 55621 more items ]

由此可见,计数法比Promise快将近1倍左右。

相关文章

  • Node.JS中如何判断递归嵌套的所有回调函数已经执行完毕,以读

    Promise 方法 Promise有一个 all 方法: 计数方法: 计数是比较常用的一种方法,其原理类似于c/...

  • js中的异步操作

    Node.js 中读取文件 回调函数嵌套造成回调地狱 Promise Promise 是异步编程的一种解决方案,比...

  • 异步问题

    什么是回调地狱(函数作为参数层层嵌套)回调函数(一个函数作为参数需要依赖另一个函数执行调用)如何解决回调地狱 pr...

  • 14.回调地狱与 Promise

    回调地狱 为了保证异步代码的执行顺序,将异步代码嵌套到回调函数中,当异步的方法多了,就会产生回调地狱(callba...

  • JQuery 动画队列简述

    先看以下代码 这段代码可以执行结果如下 刚刚那一段代码 回调函数中嵌套回调函数,特别丑!!!但是!!!还是有救的J...

  • nodejs笔记2(回调函数和事件循环)

    回调函数 Node.js 异步编程的直接体现就是回调。Node 使用了大量的回调函数,Node 所有 API 都支...

  • 如何使用async/await替代js传统回调函数的写法

    在 js/node.js 中,有很多的操作都是异步的,一般通过回调函数形式返回结果,所以非常容易写出嵌套过深甚至回...

  • 递归、回调

    递归函数:在函数的内部调用自己,递归函数应该给出口否则就会一直执行 若函数不给出口 递归的小应用 回调函数:把一个...

  • Vue - day8

    day8 Promise 引入 回调地狱 回调函数中 嵌套 其他回调函数 例子: 多个文件依次读取 解决方法: ...

  • 学习纲要:异步流程处理

    在处理复杂的异步流程时,用异步结束后,在回调函数中执行下一个异步的方式,会导致回调函数深度嵌套的问题。让代码变得难...

网友评论

      本文标题:Node.JS中如何判断递归嵌套的所有回调函数已经执行完毕,以读

      本文链接:https://www.haomeiwen.com/subject/aofslftx.html