`
xieye
  • 浏览: 830970 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

node异步进阶(2)-- Promise的连续then写法

阅读更多
node异步进阶系列文章:
node异步进阶(1)-- 回调函数经典写法
node异步进阶(2)-- Promise的连续then写法
node异步进阶(3)-- async写法


继续上回的任务,这次改用promise对象实现。

让我们疯狂的使用then吧
第三版 (串行)
var http = require('http');
var fs = require('fs');

http.createServer(function(req,res){
  if (req.url=='/') {
    getTitles(res);
  }
}).listen(80,function(){
  console.log('server start..');
});

function getTitles(res){
  var titles;
  get_file_content('/tpl/title.json') // 先抓取数据文件
  .then(JSON.parse)  // 这里顺便做一下解析,让我们尽情滥用node的异步吧!!
  .then( function(value){
    titles = value;  // 把局域变量保存到上一层变量。
    return '/tpl/template.html';//给下一个文件请求then传参
  }).then(
    get_file_content             // 再抓取模板文件
  ).then(function (tmpl){ // tmpl是上一个promis的输出
      formatHtml(titles,tmpl, res); // 调用函数全部搞定
    }
  ).catch( function (err) {
    hadError(err, res);          // 调用处理错误的函数。
  });
}

// 这是通用函数,异步读文件
function get_file_content(file)
{
  return new Promise(function (resolve, reject) {
    fs.readFile(__dirname+file, function(err,data){
      if (err) {
        reject(err);
      } else {
        resolve(data.toString() );
      }
    });
  });
}


//这是本程序主要逻辑,模板替换后,输出
function formatHtml(titles,tmpl, res) {
  var html = tmpl.replace('%', ' <li > ' +titles.join('</li > <li >') +' </li > ' );
  res.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});
  res.end(html);
}

// 通用的错误处理函数
function hadError(err, res) {
  console.log(err);
  res.end('server error.');
}


我本人的电脑是windows,node8.9,测试通过,假如故意删除一个模板文件或数据文件,会在html输出程序中给定的错误。

注意到,这种写法的要点,先定义一个返回promise对象的函数,然后每个then里面放入这个函数,也可以不放,会自动被node转换成promise对象的!

这种写法中,一般都希望在一个地方处理错误,只要任意一个地方抛异常,所以就按上面的写法,把catch放在最后即可。

返回promise对象的函数的写法,把正确的输出放在resolve里即可,
每个then的输出,就是下个then的输入,代码很连贯。

尽管如此,本任务无需获取模板文件必须在数据文件后,完全可以同时请求,加快速度,于是有下面的代码:
第四版(并发)
var http = require('http');
var fs = require('fs');

http.createServer(function(req,res){
  if (req.url=='/') {
    getTitles(res);
  }
}).listen(80,function(){
  console.log('server start..');
});

function getTitles(res){
  var files ={
    title_fun: function (){
      return get_file_content('/tpl/title.json').then(JSON.parse);
    },
    template_fun:function(){
      return get_file_content('/tpl/template.html');
    }
  };
  Promise.all([files.title_fun(), files.template_fun()]).then(function (results){
      formatHtml(results[0],results[1], res); // 按照教材说法,这里的结果顺序一定等同all的传入顺序
    }
  ).catch( function (err) {
    hadError(err, res);          // 调用处理错误的函数。
  });
}

// 这是通用函数,异步读文件
function get_file_content(file)
{
  return new Promise(function (resolve, reject) {
    fs.readFile(__dirname+file, function(err,data){
      if (err) {
        reject(err);
      } else {
        resolve(data.toString() );
      }
    });
  });
}


//这是本程序主要逻辑,模板替换后,输出
function formatHtml(titles,tmpl, res) {
  var html = tmpl.replace('%', ' <li > ' +titles.join('</li > <li >') +' </li > ' );
  res.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});
  res.end(html);
}

// 通用的错误处理函数
function hadError(err, res) {
  console.log(err);
  res.end('server error.');
}



可以看到并发请求,速度更快了,更充分利用了node的天生异步特性,充分的利用了计算机的性能。
并发的要点是all(....).then(...)这样的写法。

尽管如此,程序还是比较罗嗦,有没有更简单的写法呢?早就有了。
请继续看下一篇文章


0
0
分享到:
评论

相关推荐

    详解Node.js异步处理的各种写法

    在本文中,我们将深入探讨Node.js异步处理的几种常见方法,包括回调函数、事件驱动以及基于Promise和async/await的现代异步编程模式。 首先,我们来看**回调函数**。这是Node.js早期处理异步操作的主要方式。例如,...

    详谈nodejs异步编程

    Promise可以链式调用then方法来处理多个异步操作,并且能够优雅地处理错误。一个Promise对象的状态一旦改变就不能再次改变。这种方式可以有效避免“回调地狱”,使得异步操作的代码更加清晰。 Generator函数是ES6中...

    浅谈Express异步进化史

    在JavaScript的世界,异步编程是不可或缺的一部分,尤其是在Node.js环境中,由于其单线程特性,异步处理显得尤为重要。Express作为Node.js中最受欢迎的Web服务器框架之一,自然而然地需要面对和处理各种异步操作。...

    JavaScript Promise启示录_.docx

    在实际应用中,Promise 可以结合`async/await`语法一起使用,使得异步代码更加接近同步代码的写法,提高代码的可读性和可维护性。例如: ```javascript async function runA() { try { const resB = await B(); ...

    前端开源库-es6-promisify-all

    `es6-promisify-all` 是一个前端开源库,旨在帮助开发者将所有非 Promise 的异步方法转换为 Promise 形式,从而更好地利用 ES6 的 Promise 特性。 `Promise` 是一种状态管理机制,它有三种状态:pending(等待中)...

    Node.js模拟发起http请求从异步转同步的5种用法

    在转换异步到同步的过程中,需要注意的是,虽然代码看起来更易读,但同步写法会阻塞后续代码的执行,直至Promise对象被解决。这意味着在高并发的环境下使用同步写法可能会影响性能。因此,在实际应用中,应根据实际...

    devclass-apn-01:Node.js 中的异步编程

    async/await则是基于Promise的一种更优雅的写法,它允许我们使用类似同步代码的方式来编写异步逻辑,提高了代码的可读性和可维护性。 在Node.js中,常见的异步I/O操作包括文件系统操作(fs模块)、网络通信(http或...

    详解ES6 系列之异步处理实战

    在ES6中,异步处理经历了从回调函数到Promise再到Generator和Async/Await的重大变革,极大地提升了代码的可读性和可维护性。本篇将详细讲解这些不同方式的异步处理,并通过一个实际示例——查找指定目录下最大文件,...

    理解 Node.js 事件驱动机制的原理

    Promise允许我们使用.then()和.catch()方法来链式调用异步操作,这样可以让异步代码的书写和理解变得更接近同步代码的风格。 在Node.js中,EventEmitter和Promise并不是相互排斥的。实际上,很多现代的Node.js模块...

    字节最新前端面试题.pdf

    - Promise构造函数同步执行,then方法异步执行,遵循微任务(microtask)队列,会在当前脚本或任务队列之后执行。 12. 实现new操作符: - new操作符用于创建对象实例,本质上是对函数进行调用并返回新对象。 13. ...

    Axios 技术文档.pdf

    Axios是一个基于Promise的HTTP请求客户端,适用于浏览器和Node.js环境中。它允许开发者发送各种HTTP请求,比如GET、POST、PUT、DELETE等,并且能自动处理JSON数据的序列化和反序列化。Axios还提供请求拦截和响应拦截...

    react + ts or vue + ts 通用axios封装的方法。

    Axios是一个基于Promise的HTTP库,它可以在浏览器和node.js中使用。它具有丰富的特性,如拦截请求和响应、转换请求和响应数据、取消请求、自动转换JSON数据等,因此在前端开发中广泛被采用。 在React或Vue项目中,...

    nodejs:node.js中的嵌套异步示例

    为了避免回调函数的嵌套,我们使用了Promise来包装异步操作,并通过`.then()`和`.catch()`链式调用来处理结果和错误。 此外,Node.js提供了更高级的异步控制流工具,如async/await,可以进一步提高代码的可读性和可...

    深入解析koa之异步回调处理

    Promise是JavaScript中用于处理异步操作的一种对象,它代表了一个最终会完成或失败的异步操作,并且允许我们链式调用then方法来处理这些异步操作的结果,从而避免了回调地狱。 在koa框架中,结合generator和Promise...

    js代码-js计算的先后顺序

    - ES7引入的异步控制流语法,使得异步代码更接近同步代码的写法。 - `async`函数返回一个Promise,`await`关键字用于等待Promise的结果。 9. **作用域链**: - 当在函数内部查找变量时,会沿着作用域链向上查找...

    浅谈关于JS下大批量异步任务按顺序执行解决方案一点思考

    #### 方案2:模仿Node.js的EventEmitter 为了改进方案1的缺点,作者尝试引入观察者模式,使用EventEmitter来控制任务的循环执行。这种方式可以更清晰地组织代码逻辑,并且通过事件监听和触发机制来控制异步任务的...

    百度2019校招Web前端工程师笔试卷(第三批).pdf

    Promise链中调用了resolve(),没有调用reject(),因此then()方法中的回调函数会被执行,变量name的值会变成'2'。由于Promise链后还有name='4';的语句,根据异步操作的特性,name='4'会在Promise链中的回调函数执行...

    JavaScript快速查询手册

    2. Promise:处理异步操作的更优雅方式,具有then和catch方法来处理成功和失败的情况。 3. async/await:基于Promise的语法糖,使得异步代码看起来像同步代码,提高代码可读性。 七、模块化 1. CommonJS:Node.js...

    ES7之Async/await的使用详解

    ES6引入的Promise解决了这一问题,而ES7的Async/Await则进一步优化了Promise的使用体验,使得异步代码更接近同步的写法。 首先,我们需要了解Promise。Promise是一个代表未来某个时刻可能完成或失败的操作的对象。...

Global site tag (gtag.js) - Google Analytics