# 概述

1.程序=数据结构+算法

2.一个类就在设计一个数据结构,一个接口就在写一 个自己设计的算法或者应用经典的算法

3.遇到在一个大的有序列表查找某一个纪录可以用二 分法之类的算法来提升查找效率。

4.要写出优雅、结构良好的程序,的确是需要一定的 算法功底的。

5.程序有很多for的时候就可以考虑算法了, 程序数据杂乱无章有必要设计数据结构了。

An image

点的执行优先级比较高

console.log(a);//undefine

var s = [];
var arr = s;
for (var i = 0; i < 3; i++) {
  var pusher = {
    value: "item"+i
  },tmp;
  if (i !== 2) {
    tmp = []
    pusher.children = tmp
  }
  arr.push(pusher);
  arr = tmp;
}
console.log(s[0]);
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 堆和栈

内存栈:函数执行的时候会把局部变量压到一个栈里面。

内存堆:是指存放new出来动态变量的地方

An image

1、栈区(stack):又编译器自动分配释放,存放函数的参数值,局部变量 的值等,其操作方式类似于数据结构的栈。

2、堆区(heap):一般是由程序员分配释放,若程序员不释放的话,程 序结束时可能由OS回收,值得注意的是他与数据结构的堆是两回事,分配方式 倒是类似于数据结构的链表。

3、全局区(static):也叫静态数据内存空间,存储全局变量和静态变 量,全局变量和静态变量的存储是放一块的,初始化的全局变量和静态变量放 一块区域,没有初始化的在相邻的另一块区域,程序结束后由系统释放。

4、文字常量区:常量字符串就是放在这里,程序结束后由系统释放。 5、程序代码区:存放函数体的二进制代码。

# 递归

let ids = [1,2,3,4];
(function sendResquest() {
  let id = ids.shift();
  if(id) {
     $.ajax(url:'xxx.php',methods:'get',data:{id},()=>{
       console.log('finish!');
       sendResquest()
     })
  }else{
 		console.log('finish!');
  }
})()
1
2
3
4
5
6
7
8
9
10
11
12

递归改成for 这样就不会产生递归的调用执行记录

串形请求不堵塞

(async()=>{
  const ids = [1,2,3,4];
  function request(item) {
    return new Promise((resolve,reject)=>{
      const result = $.ajax(url:'xxx.php',methods:'get',data:{item})
    	result.done((value)=>{resolve(value)});
      result.error((e)=>{reject(e)});
    })
  }
  for(let item of ids) {
    await request(item)
  }
})()
1
2
3
4
5
6
7
8
9
10
11
12
13

An image

An image

虽然函数调用记录没有了,但是依然会有函数的调用针

# koa实现

An image

app.js

const Koa = require('./Koa/application');
const app = new Koa();


app.context.render = function(viewpath) {
  this.res.setHeader('Content-Type','text/html;charset=utf-8');
  //Io html 文件
  //ctx.end();
  // console.log('服务端渲染原理',viewpath);
  return viewpath
}

app.use(async (ctx, next) => {
  console.log(1);
  await next();
  console.log(5);
});

app.use(async (ctx, next) => {
  console.log(2);
  await next();
  console.log(4);
});
app.use(async (ctx, next) => {
  console.log(3);
  // console.log(xxx);
  // ctx.body = 'Hello World';
  ctx.body = ctx.render('今天星期日🌞');
  // ctx.status = 500;
});

app.listen(3000,()=>{
  console.log('server start!')
});

app.on('error',(data)=>{
  console.log('🍊',data);
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

application.js

const http = require('http');
let context = require('./context');
let request = require('./request');
let response = require('./response');
const EventEmitter = require('events');

class Koa extends EventEmitter {
    constructor() {
        super();
        this.middlewares = [];
        this.context = context;
        this.request = request;
        this.response = response;
    }

    listen(...args) {
        //传入一个回调函数,处理所有的中间件
        let server = http.createServer(this.callback());
        server.listen(...args)
    }

    compose() {
        return async (ctx) => {
            function createNext(middleware, oldNext) {
                return async () => {
                    await middleware(ctx, oldNext)
                }
            }

            let len = this.middlewares.length;
            let next = async () => {
                return Promise.resolve();
            }
            for (let i = len - 1; i >= 0; i--) {
                let currentMiddleWare = this.middlewares[i];
                next = createNext(currentMiddleWare, next);
            }
            await next();
        }
    }

    repondseBody(ctx) {
        let context = ctx.body;
        if (typeof context == 'string') {
            ctx.res.end(context)
        } else if (typeof context == 'object') {
            ctx.res.end(JSON.stringify(context))
        }
    }

    onerror(error, ctx) {
        if (error.code == 'ENOENT') {
            ctx.status = 404;
        } else{
            ctx.status = 500;
        }

        let msg = error.message || '服务器错误❌';
        ctx.res.end(msg);
        this.emit('error',error)
    }

    callback() {
        return (req, res) => {
            let ctx = this.createContext(req, res);
            const repond = () => this.repondseBody(ctx);
            const onerror = (error) => this.onerror(error,ctx);
            let fn = this.compose();
            return fn(ctx).then(repond).catch(onerror);
        }
    }

    createContext(req, res) {
        let ctx = Object.create(this.context);
        ctx.request = Object.create(this.request);
        ctx.response = Object.create(this.response);
        ctx.req = ctx.request.req = req;
        ctx.res = ctx.response.res = res;
        return ctx;
    }

    use(middleware) {
        this.middlewares.push(middleware);
    }
}

module.exports = Koa;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

context.js

let proto = {};
let requestGet = ['query'];
let requestSet = [];
let responseGet = ['body', 'status'];
let responseSet = ['body', 'status'];

function delegateGet(property, name) {
    proto.__defineGetter__(name, function (val) {
        return this[property][name];
    })
}

function delegateSet(property, name) {
    proto.__defineSetter__(name, function (val) {
        // console.log('🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎',this)
        console.log('🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎val',val)
        console.log('🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎property',property);
        console.log('🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎name',name);
        this[property][name] = val;
    })
}

requestGet.forEach(ele => {
    delegateGet('request', ele)
})

requestSet.forEach(ele => {
    delegateSet('request', ele)
})

responseGet.forEach(ele => {
    delegateGet('response', ele)
})

responseSet.forEach(ele => {
    delegateSet('response', ele)
})

module.exports =  proto;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

request.js

const url = require('url');
module.exports =  {
    get query() {
        return url.parse(this.req.url);
    }
}
1
2
3
4
5
6

response.js

module.exports = {
    get body() {
        return this._body;
    },
    set body(data) {
        // console.log('🍎data',data);
        // console.log('🍎',this);
        this._body = data;
    },
    get status() {
        return this.res.statusCode;
    },
    set status(statusCode) {
        this.res.statusCode = statusCode;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

An image