• nodejs 回调地狱解决 promise async


    nodejs毁掉地狱是一直被人诟病的,以下总结一下解决毁掉地狱的一些方法。(暂时研究的比较浅)

    1.promise

    promise模式在任何时刻都处于以下三种状态之一:未完成(unfulfilled)、已完成(resolved)和拒绝(rejected)。以CommonJS Promise/A 标准为例,promise对象上的then方法负责添加针对已完成和拒绝状态下的处理函数。then方法会返回另一个promise对象,以便于形成promise管道,这种返回promise对象的方式能够支持开发人员把异步操作串联起来,如then(resolvedHandler, rejectedHandler); 。resolvedHandler 回调函数在promise对象进入完成状态时会触发,并传递结果;rejectedHandler函数会在拒绝状态下调用。(其中rejectedHandler可选)。

    以下为一个有几级嵌套的函数,看起来比较令人恶心。(如果换成缩进四个字符可想而知)

    'use strict';
    const md = require('markdown-it')();
    const fs = require('fs');
    fs.watchFile('nodejs.md', (curr, prev) => {
      let mdStr = fs.readFile('./nodejs.md', 'utf-8', (err, data) => {
        let mdData = md.render(data);
        let htmlTemplate = fs.readFile('./index.html', 'utf-8', (err, data) => {
          let html = data.replace('{{content}}', mdData);
          console.log(mdData);
          fs.writeFile('./nodejs.html', html, 'utf-8', (err, data) => {
            if (err) {
              throw err;
            } else {
              console.log('OK');
            }
          });
        });
      });
    });

    一下用promise的方式实现同样的效果,首先把异步函数封装一下,然后下面可以指教调用。可能看起来代码比之前的版本更多,但是封装的异步函数是可以复用的。等任务多了就不显得代码多了。(但看最后调用函数的部分是不是优雅了不少)

    'use strict';
    const fs = require('fs');
    const md = require('markdown-it')();
    var Q = require('q');
    
    function fs_readFile(file, encoding) {
    
      var deferred = Q.defer();
      fs.readFile(file, encoding, function(err, data) {
        if (err) deferred.reject(err); // rejects the promise with `er` as the reason
        else
          deferred.resolve(data) // fulfills the promise with `data` as the value
      });
      return deferred.promise; // the promise is returned
    }
    
    function fs_writeFile(file, data, encoding) {
      var deferred = Q.defer();
      fs.writeFile(file, data, encoding, function(err, data) {
        if (err) deferred.reject(err); // rejects the promise with `er` as the reason
        else deferred.resolve(data); // fulfills the promise with `data` as the value
      });
      return deferred.promise ;// the promise is returned
        //return 1; // the promise is returned
    }
    
    function fs_watchFile(file, curr, prev) {
      var deferred = Q.defer();
      fs.watchFile(file, function(curr, prev) {
        if (!prev) deferred.reject(err); // rejects the promise with `er` as the reason
        else deferred.resolve(curr); // fulfills the promise with `data` as the value
      });
      return deferred.promise // the promise is returned
    }
    
    function markdowm_convert(file, encoding, mdData) {
    
      var convertData = md.render(mdData);
      console.log(convertData);
      var deferred = Q.defer();
      fs.readFile(file, encoding, function(err, data) {
        if (err) deferred.reject(err); // rejects the promise with `er` as the reason
        else {
          data = data.replace('{{content}}', convertData);
          deferred.resolve(data); // fulfills the promise with `data` as the value
        }
      })
      return deferred.promise; // the promise is returned
    }
    
    
    
    
    // ===============promise实现  =====================
    fs_watchFile('nodejs.md')
      .then(function() {
        return fs_readFile('./nodejs.md', 'utf-8');
      })
      .then(function(mdData) {
        return markdowm_convert('./index.html', 'utf-8', mdData);
      })
      .then(function(data) {
        fs_writeFile('./nodejs.html', data, 'utf-8');
      });

     2.async

    node的async包有多的数不清的方法我暂时只实验了一个waterfall

    waterfall瀑布流的意思和async中另一个函数series差不多都是按照顺序执行,不同之处是waterfall每执行完一个函数都会产生一个值,然后把这个值给下一个函数用。

    以下是嵌套了两级的读写文件程序

    fs.readFile('01.txt','utf-8',function(err,date){
      fs.writeFile('02.txt',date,'utf-8',function(err,date){
        console.log('复制完了');
      });
    })

    用async.waterfall 后代码如下

    async.waterfall([
      function(cb){
        fs.readFile('01.txt','utf-8',function(err,result){
          cb(err,result);
        });
    
      },function(result,cb){
        fs.writeFile('02.txt',result,'utf-8',function(err,result){
          cb(err,result);
        });
      }
      ],function(err,result){
     console.log('复制完了');
    })

     另外最近学习了generator及node co库的源码分析。详见这里

  • 相关阅读:
    是否有人会想起
    春风下也有落叶
    to kongove:呵呵~是啊,偶尔吹得玩下,仅当娱乐而已……
    木头人の狂想
    夜行静思湖
    [学习标准库]math.h
    [学习标准库]ctype.h
    [学习标准库]stdio.h
    句子
    [学习标准库]assert.h
  • 原文地址:https://www.cnblogs.com/ytu2010dt/p/5486854.html
Copyright © 2020-2023  润新知