关于promise的疑惑,求点思路
发布于 8 年前 作者 xunull 4505 次浏览 来自 问答

QQ20160825-0.png

前三个箭头是promise的函数,在前三个执行完后,但是执行到第四个箭头的时候,代码就没有继续执行下去了,不管此处是promise 形式的方法还是普通的回调方法 思考了很久没有想清楚为什么没有执行,可能会是prmoise的嵌套不能太多么? 下面是实际的代码

var path = require('path');
var fs = require('fs');
var yaml = require('js-yaml');
var exec = require('child_process').exec;
var express = require('express');
// 但是这个global 如果很多应用都使用就会被污染了
var logger = global.thisapp.logger;
var express_app = global.thisapp.express_app;


// app的根目录,此目录下的文件夹 都是各个项目
var apps_root = path.join(__dirname, '../../' + global.thisapp.appConfigYaml.apps_root);

console.log(apps_root);

function readFile(_path) {
    return new Promise((resolve, reject) => {
        fs.readFile(_path, 'utf8', (err, data) => {
            if (err) {
                 reject(err);
            } else {
                 resolve(data.toString());
            }
        });
    });
}

function readdir(_path) {
    return new Promise((resolve, reject) => {
        fs.readdir(_path, (err, files) => {
            if (err) {
                 reject(err);
            } else {
                 resolve(files);
            }
        });
    });
}

function fileStat(_path) {
    return new Promise((resolve, reject) => {
        fs.stat(_path, function(err, stats) {
            if (err) {
                 reject(err);
            } else {
                 resolve(stats);
            }
        });
    });
}

function init() {
    readdir(apps_root).then((files)=>{
        for (let file of files) {
            let filePath = path.join(apps_root, file);
            fileStat(filePath).then((stats)=>{
                if(stats.isDirectory()){
                  fileStat(path.join(filePath, 'index.js')).then((stats)=>{
                      execChildProcess('node ' + path.join(tempPath, 'index.js'));
                  },(err)=>{
                      logger.error(file,'下没有index.js文件');
                      // promise 的形式 下面代码也不执行
                      fs.readFile(path.join(tempPath, 'web.yaml'), 'utf8', (err, data) => {
                          if (err) {
                              logger.info('读取配置文件出错');
                          } else {
                            var webYaml = yaml.safeLoad(data.toString());
                            loadController(webYaml, tempPath, tempFile);
                          }
                      });

                      // readFile(path.join(tempPath, 'web.yaml')).then((data)=>{
                      //   var webYaml = yaml.safeLoad(yamlFile);
                      //   loadController(webYaml, tempPath, tempFile);
                      // },(err)=>{
                      //     logger.info('读取配置文件出错');
                      // });
                  });
                }
            },(err)=>{
                logger.error('读取',file,'出错');
            });
        }
    },(err)=>{
      logger.info('读取',apps_root,'文件夹出错');
    });
}

function execChildProcess(directive) {
  exec(directive,function(err,stdout,stderr){
    if (err) {
        logger.info('子进程执行出错');
    } else {
        logger.info('子进程正常执行');
        // logger.info(stdout);
        // logger.error(stderr);
    }
  });
}

init();

function loadController(webYaml, rootPath, rootName) {
    logger.info(111111111111111111111);
}

12 回复

这代码,你自己看的清楚嘛,另外第四个是错误回调,你确定你fileStat抛错了? 你该休息下换换脑子了~

@ncuzp 我这段程序是这样的,第三个的filestat 是为了判断是否有这个文件存在,如果这个文件不存在,就会执行第四个箭头部分的语句。

先把你的代码整理的好看一点,再来求人。就好比你穿衣服,扣子都没有系齐,就问别人,你这衣服漂不漂亮一样。

反正我觉得promise的目的就是减少嵌套 尽量只有一层的- -所以你这个代码看的很累- -

@xunull 那check下你的fileStat是不是写的有问题,这个代码贴出来看看

@ncuzp 我把代码都贴出来了

@xunull 调试下就可以吧,在当前目录下没有index.js文件的情况下,fileStat是否执行了reject?, 另外logger.error(file,'下没有index.js文件');这个有执行?

@ncuzp 对,你说的这个logger 这句话执行完后,后面的代码都没没有执行(即使我这这个logger后面写的,还是一句简单的logger),就是已经开始执行这个部分的代码了

@xunull 去掉试试呢?估计抛错了吧,在fileStat Promise链后面加个catch打印错误看看

@ncuzp 兄弟谢谢你,我加个try catch 看出来我的错误了,变量名错误了,在promise中的错误看来需要小心处理。非常感谢你!

@xunull 找不到错误的时候,try catch是个神器。

'use strict';
global.Promise = require("bluebird");
var fs = Promise.promisifyAll(require("fs"));
//promise链
exports.list = ( path ) => {
    return new Promise(( res,rej ) => {
        fs.statAsync( path ).then((stat) => {
            if( stat.isFile() ) {
                res([{path:path,flag:1}]);
            } else {
                fs.readdirAsync(path).then((files)=>{
                    Promise.map( files,( file ) => {
                        var p = path.concat("/",file);
                        return fs.statAsync(p).then((stat) => {
                            if( stat.isFile() ) {
                                return {path:p,flag:1};
                            } else {
                                return {path:p,flag:0};
                            }
                        });
                    }).then(( list ) => {
                        res(list);
                    });
                });
            }
        });
    });
}
exports.list1 = Promise.coroutine(function* ( path ) {
    var stat = yield fs.statAsync(path);
    if( stat.isFile() ) {
        return [{path:path,falg:1}];
    }

    var files = yield fs.readdirAsync(path);
    var list = yield Promise.map(files,( file )=>{
        var p = path.concat("/",file);
        return fs.statAsync(p).then(( stat ) => {
            if( stat.isFile() ) {
                return {path:p,flag:1};
            } else {
                return {path:p,flag:0};
            }
        });
    });

    return list;
});
回到顶部