Node使用promise封装异步函数

Node使用promise封装异步函数

什么是Promise

  • romise是一个对象,它通常代表一个在未来可能完成的异步操作。这个操作可能成功也可能失败,所以一个Promise对象一般有3个状态:Pending,Fulfilled,Rejected。分别代表未完成、成功完成和操作失败。一旦Promise对象的状态从Pending变成Fulfilled或者Rejected任意一个,它的状态都没有办法再被改变。
  • 一个Promise对象通常会有一个then方法,这个方法让我们可以去操作未来可能成功后返回的值或者是失败的原因。

promise有什么用?

  • 回调函数的多重嵌套让代码变的难以维护,利用CommonJs的Promise来封装异步函数,使用统一的链式API来摆脱多重回调的噩梦。

回调地狱:

'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实现

一下用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');
  });

then方法

语法规则:

promise.then(onFulfilled, onRejected)

显而易见的是,then方法接受两个参数,它们通常是两个函数,一个是用来处理操作成功后的结果的,另一个是用来处理操作失败后的原因的,这两个函数的第一个参数分别是成功后的结果和失败的原因。如果传给then方法的不是一个函数,那么这个参数会被忽略。

then方法的返回值是一个Promise对象,这一个特点允许我们链式调用then来达到控制流程的效果。这里有许多细节上的问题,比如值的传递或者错误处理等。

你可能感兴趣的:(Node使用promise封装异步函数)