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(‘复制完了‘); })
时间: 2024-10-09 18:55:59