来自Koa官网对于Koa的简介:

koa 是由 Express 原班人马打造的,致力于成为一个更小、更富有表现力、更健壮的 Web 框架。 使用 koa 编写 web 应用,通过组合不同的 async函数,可以免除重复繁琐的回调函数嵌套, 并极大地提升错误处理的效率。koa 不在内核方法中绑定任何中间件, 它仅仅提供了一个轻量优雅的函数库,使得编写 Web 应用变得得心应手。

简而言之Koa就是基于NodeJs的Web开发框架

Koa2相较Koa1最大的区别就是中间件的写法不同,Koa1使用Generator,Koa2使用async/await语法。由于Koa2使用async/await语法,所以在学习之前,请使用v7.6.0+的Node

Koa2快速开始

安装Koa2

npm init
npm install koa

一个简单的Hello World程序开场,

//index.js
const Koa = require('koa')
const app = new Koa() app.use( async ctx => {
ctx.body = 'Hello World'
}) app.listen(3000,()=>{
console.log("server is running at 3000 port");
})

启动demo

node index.js

访问http://localhost:3000,页面如下所示

使用Async/Await语法

在讲解Async/Await之前,有必要简单讲一下javascript的异步发展历程,并给每种异步的方式给一段示例代码

异步主要经历了这么几个过程:

Es6之前:

  • 回调函数(callback)

Es6

  • Promise对象
  • Generator函数

Es7

  • async/await语法
使用async/await
  • async用于声明一个function是异步的
  • await只能出现在用async修饰的function中
async到底起什么作用
async function test(){
return "Hello World";
} var result=test();
console.log(result);
//打印Promise { 'Hello World' }

async函数返回一个promise对象,如果在async函数中返回一个直接量,async会通过Promise.resolve封装成Promise对象。

我们可以通过调用promise对象的then方法,获取这个直接量。

test().then(data=>{
console.log(data);
})
//打印 "Hello World"

那如过async函数不返回值,又会是怎么样呢?

//不返回值
async function test(){ }
var result=test();
console.log(result);
//打印Promise { undefined }
await到底在等什么

await会暂停当前async的执行,await会阻塞代码的执行,直到await后的表达式处理完成,代码才能继续往下执行。

await后的表达式既可以是一个Promise对象,也可以是任何要等待的值。

如果await等到的是一个 Promise 对象,await 就忙起来了,它会阻塞后面的代码,等着 Promise 对象 resolve,然后得到 resolve 的值,作为 await 表达式的运算结果。

上边你看到阻塞一词,不要惊慌,async/await只是一种语法糖,代码执行与多个callback嵌套调用没有区别,本质并不是同步代码,它只是让你思考代码逻辑的时候能够以同步的思维去思考,避开回调地狱,简而言之-async/await是以同步的思维去写异步的代码,所以async/await并不会影响node的并发数,大家可以大胆的应用到项目中去!

如果它等到的不是一个 Promise 对象,那 await 表达式的运算结果就是它等到的东西。

举个例子

function A() {
return "Hello ";
} async function B(){
return "World";
} async function C(){
//等待一个字符串
var s1=await A();
//等待一个promise对象,await的返回值是promise对象resolve的值,也就是"World"
var s2=await B();
console.log(s1+s2);
} C();
//打印"Hello World"

华丽的分割线,async/await讲完了,如果大家对别的异步方式感兴趣的话,可以继续往下看,不感兴趣,到此为止啊!


回调函数(callback)

回调函数就是一个参数,将这个函数作为参数传到另一个函数里面,当那个函数执行完之后,再执行传进去的这个函数。这个过程就叫做回调,回调其实按字面意思也很好理解,先处理主函数,回头再调用作为参数传进来的这个参数,举个栗子。

function A(callback){
console.log("我是主函数");
callback();
} function B(){
console.log("我是回调函数");
} A(B);
//输出结果
我是主函数
我是回调函数
Promise对象

**Promise **对象用于一个异步操作的最终完成(或失败)及其结果值的表示。(简单点说就是处理异步请求。我们经常会做些承诺,如果我赢了你就嫁给我,如果输了我就嫁给你之类的诺言。这就是promise的中文含义:诺言,一个成功,一个失败。)

​ ---MDN对Promise的解释

例子:使用Promise封装fs模块中的readFile()方法

创建一个Promise对象

​ Promise构造函数的参数是一个函数,我们把它称为处理器函数,处理器函数接收两个函数reslovereject作为其参数,当异步操作顺利执行则执行reslove函数, 当异步操作中发生异常时,则执行reject函数。通过resolve传入得的值,可以在then方法中获取到,通过reject传入的值可以在chatch方法中获取到,

​ 因为thencatch都返回一个相同的promise对象,所以可以进行链式调用。

const fs=require("fs");

//path参数是文件的路径,返回一个Promise对象
function readFileByPromise(path){
//显示返回一个Promise对象
return new Promise((resolve,reject)=>{
fs.readFile(path,"utf8",function(err,data){
if(err)
reject(err);
else
resolve(data);
})
})
} readFileByPromise("a.txt").then( data =>{
//打印文件中的内容
console.log(data);
}).catch( error =>{
//抛出异常,
console.log(error);
})
Generator函数

Generator是 ES6 的新特性,中文译为生成器,在以前一个函数中的代码要么被调用,要么不被调用,还不存在能暂停的情况,Gnenerator让代码暂停成为可能,定义一个生成器很简单,在函数名前加个*****号,使用上也与普通函数有区别,看下面的例子。

一个简单的例子

1、定义生成器函数

function *Calculate(a,b){
let sum=a+b;
console.log(sum);
let sub=a-b;
console.log(sub);
}

2、创建Generator对象

Generator函数不能直接调用,直接调用Generator函数会返回一个Generator对象,只有调用Generator对象的next()方法才能执行函数里的代码。

let gen=Calculate(2,7);

3、执行Generator函数代码

gen.next();
//打印
//9
//-5
yield关键字

其实单独介绍Generator并没有太大的价值,要配合yield关键字,才能真正发挥Generator的价值。yield能将生Generator函数的代码逻辑分割成多个部分,下面改写上面的生成器函数。

function *Calculate(a,b){
let sum=a+b;
yield console.log(sum);
let sub=a-b;
yield console.log(sub);
}
let gen=Calculate(2,7);
gen.next();
//输出
//9

可以看到这段代码执行到第一个yield处就停止了,如果要让里边所有的代码都执行完就得反复调用next()方法

let gen=Calculate(2,7);
//因为上边代码我用了两个yield,所以调用了两次next()
gen.next();
gen.next();
//输出
//9
//-5
Generator与异步编程

实现一个功能,先读取a.txt,再读取b.txt,必须按顺序读取。

const fs=require("fs");

fs.readFile("a.txt",(err,data)=>{
if(!err){
console.log(data);
fs.readFile("b.txt",(err,data)=>{
if(!err)
console.log(data);
})
}
})

这是一个典型的回调嵌套,过多的回调嵌套造成代码的可读性和可维护性大大降低,形成了令人深恶痛绝的回调地狱,试想如果有一天让你按顺序读取10个文件,那就得嵌套10层,再或者需求变更,读取顺序要变了先读b.txt,再度a.txt那改来真的不要太爽。

使用Generator改写上面的代码

Generator函数的强大在于允许你通过一些实现细节来将异步过程隐藏起来,依然使代码保持一个单线程、同步语法的代码风格。这样的语法使得我们能够很自然的方式表达我们程序的步骤/语句流程,而不需要同时去操作一些异步的语法格式

const fs=require("fs");

function readFile(path) {
fs.readFile(path,"utf8",function(err,data){
it.next(data);
})
} function *main() {
var result1 = yield readFile("a.txt");
console.log(result1); var result2 = yield readFile("b.txt");
console.log(result2); var result3 = yield readFile("c.txt");
console.log(result3);
} var it = main();
it.next();

koa2教程(一)-快速开始的更多相关文章

  1. Spring_MVC_教程_快速入门_深入分析

    Spring MVC 教程,快速入门,深入分析 博客分类: SPRING Spring MVC 教程快速入门  资源下载: Spring_MVC_教程_快速入门_深入分析V1.1.pdf Spring ...

  2. Selenium 2.0 WebDriver 自动化测试 使用教程 实例教程 API快速参考

    Selenium 2.0 WebDriver 自动化测试 使用教程 实例教程 API快速参考 //System.setProperty("webdriver.firefox.bin" ...

  3. koa2+koa-generator+mysql快速搭建nodejs服务器

    koa2+koa-generator+mysql快速搭建nodejs服务器 用koa的脚手架koa-generator可以快速生成项目骨架,可以用于发开或者测试接口 https://github.co ...

  4. Spring Data JPA系列2:SpringBoot集成JPA详细教程,快速在项目中熟练使用JPA

    大家好,又见面了. 这是Spring Data JPA系列的第2篇,在上一篇<Spring Data JPA系列1:JDBC.ORM.JPA.Spring Data JPA,傻傻分不清楚?给你个 ...

  5. Spring Boot 2.x基础教程:快速入门

    简介 在您第1次接触和学习Spring框架的时候,是否因为其繁杂的配置而退却了?在你第n次使用Spring框架的时候,是否觉得一堆反复黏贴的配置有一些厌烦?那么您就不妨来试试使用Spring Boot ...

  6. [转]ASP.NET MVC 5 学习教程:快速入门

    本教程将使用Visual Studio 2013手把手教你构建一个入门的ASP.NET MVC5 Web应用程序.本教程配套的C#源码工程可通过如下网址下载:C#版本源码链接.同时,请查阅 Build ...

  7. Quartz教程:快速入门

    原文链接 | 译文链接 | 翻译:nkcoder | 校对:方腾飞 本系列教程由quartz-2.2.x官方文档翻译.整理而来,希望给同样对quartz感兴趣的朋友一些参考和帮助,有任何不当或错误之处 ...

  8. iOS 国际化最新最全教程+如何快速国际化一个现成APP

    同学面试时遇到一个问题,面试官问他,有一个现成的APP马上要上线了,怎么在不改原来代码,也不改xib.storyboard里的文字的情况下快速实现国际化.这里应同学请求写下此教程.反正国际化的步骤都要 ...

  9. Django博客开发教程,Django快速开发个人blog

    学DjangoWEB框架,估计大部分的朋友都是从Blog开发开始入门的,Django中文网发布了一个Django开发教程,这个教程简单易懂,能让你快速的使用Django开发一个漂亮的个人blog,是D ...

随机推荐

  1. 解决Unable to find setter method for attribute: [commandName]

    最近学习springmvc的表单标签库,其中form标签主要用于渲染HTML表单,而form标签有很多属性,可供选择,其中一般来说(以前)最重要的是commandName属性,因为它定义了模型属性的名 ...

  2. TextMesh Pro Emoji Align With Text(表情和文字对齐)

    前言 MMO游戏中需要富文件组件,大体功能包括图文混排,表情,超链接,文字动画等富文本功能,且DC数占用少. 本文选择Unity免费提供的TextMesh Pro 解决方案. 软件环境 Unity3D ...

  3. 自学Python5.1-模块简介

    模块简介 在C语言中如果要引用sqrt这个函数,必须用语句"#include<math.h>"引入math.h这个头文件,否则是无法正常进行调用的.那么在Python中 ...

  4. Python 项目实践一(外星人入侵小游戏)第五篇

    接着上节的继续学习,在本章中,我们将结束游戏<外星人入侵>的开发.我们将添加一个Play按钮,用于根据需要启动游戏以及在游戏结束后重启游戏.我们还将修改这个游戏,使其在玩家的等级提高时加快 ...

  5. Laravel学习笔记(一)

         根据国外的调查,Laravel是最流行的框架,最近公司需要PHP的开发人员,但是一直招不到人,只好亲自上阵研究一下.由于以前对PHP只是大致了解,这次学习开始的时候也挺挠头的,到今天稍微入了 ...

  6. 微信小程序教学第三章第四节(含视频):小程序中级实战教程:下拉更新、分享、阅读标识

    下拉更新.分享.阅读标识 本文配套视频地址: https://v.qq.com/x/page/h0554i4u5ob.html 开始前请把 ch3-4 分支中的 code/ 目录导入微信开发工具 这一 ...

  7. Python 项目实践二(生成数据)第二篇之随机漫步

    接着上节继续学习,在本节中,我们将使用Python来生成随机漫步数据,再使用matplotlib以引人瞩目的方式将这些数据呈现出来.随机漫步是这样行走得到的路径:每次行走都完全是随机的,没有明确的方向 ...

  8. Anaconda多版本Python管理

    Anaconda是一个集成python及包管理的软件,记得最早使用时在2014年,那时候网上还没有什么资料,需要同时使用py2和py3的时候,当时的做法是同时安装Anaconda2和Anaconda3 ...

  9. KD树小结

    很久之前我就想过怎么快速在二维平面上查找一个区域的信息,思考许久无果,只能想到几种优秀一点的暴力. Kd树就是干上面那件事的. 别的不多说,赶紧把自己的理解写下来,免得凉了. KD树的组成 以维护k维 ...

  10. bzoj 3717: [PA2014]Pakowanie

    Description 你有n个物品和m个包.物品有重量,且不可被分割:包也有各自的容量.要把所有物品装入包中,至少需要几个包? Input 第一行两个整数n,m(1<=n<=24,1&l ...