乐趣区

关于前端:请求响应原理及HTTP协议学习记录三

5. Node.js 异步编程

5.1 同步 API, 异步 API
 // 门路拼接
 const public = path.join(__dirname, 'public');
 // 申请地址解析
 const urlObj = url.parse(req.url);
 // 读取文件
 fs.readFile('./demo.txt', 'utf8', (err, result) => {console.log(result);
 });

同步 API:只有以后 API 执行实现后,能力继续执行下一个 API

console.log('before'); 
console.log('after');

异步 API:以后 API 的执行不会阻塞后续代码的执行

console.log('before');
setTimeout(() => {console.log('last');
}, 2000);
console.log('after');
5.2 同步 API, 异步 API 的区别(获取返回值)

同步 API 能够从返回值中拿到 API 执行的后果, 然而异步 API 是不能够的

    // 同步
  function sum (n1, n2) {return n1 + n2;} 
  const result = sum (10, 20);
    // 异步
  function getMsg () {setTimeout(function () {return { msg: 'Hello Node.js'}
      }, 2000);
  }
  const msg = getMsg ();
5.3 回调函数

本人定义函数让他人去调用。

  // getData 函数定义
 function getData (callback) {}
  // getData 函数调用
 getData (() => {});
5.4 应用回调函数获取异步 API 执行后果
function getMsg (callback) {setTimeout(function () {callback ({ msg: 'Hello Node.js'})
    }, 2000);
}
getMsg (function (msg) {console.log(msg);
});
5.5 同步 API, 异步 API 的区别(代码执行程序)

同步 API 从上到下顺次执行,后面代码会阻塞前面代码的执行

for (var i = 0; i < 100000; i++) {console.log(i);
}
console.log('for 循环前面的代码');

异步 API 不会期待 API 执行实现后再向下执行代码

console.log('代码开始执行'); 
setTimeout(() => { console.log('2 秒后执行的代码')}, 2000);
setTimeout(() => { console.log('"0 秒" 后执行的代码 ')}, 0); 
console.log('代码完结执行');
5.6 代码执行程序剖析
console.log('代码开始执行');
setTimeout(() => {console.log('2 秒后执行的代码');
}, 2000); 
setTimeout(() => {console.log('"0 秒" 后执行的代码 ');
}, 0);
console.log('代码完结执行');

5.7 Node.js 中的异步 API
 fs.readFile('./demo.txt', (err, result) => {});
 var server = http.createServer();
 server.on('request', (req, res) => {});

如果异步 API 前面代码的执行依赖以后异步 API 的执行后果,但实际上后续代码在执行的时候异步 API 还没有返回后果,这个问题要怎么解决呢?

需要:顺次读取 A 文件、B 文件、C 文件

const fs = require('fs');

fs.readFile('./1.txt', 'utf8', (err, result1) => {console.log(result1)
    fs.readFile('./2.txt', 'utf8', (err, result2) => {console.log(result2)
        fs.readFile('./3.txt', 'utf8', (err, result3) => {console.log(result3)
        })
    })
});
5.8 Promise

Promise 呈现的目标是解决 Node.js 异步编程中回调天堂的问题。

let promise = new Promise((resolve, reject) => {setTimeout(() => {if (true) {resolve({name: '张三'})
        }else {reject('失败了') 
        } 
    }, 2000);
});
promise.then(result => console.log(result); // {name: '张三'})
       .catch(error => console.log(error); // 失败了 )

需要:顺次读取 A 文件、B 文件、C 文件

function p1 () {return new Promise ((resolve, reject) => {fs.readFile('./1.txt', 'utf8', (err, result) => {resolve(result)
        })
    });
}

function p2 () {return new Promise ((resolve, reject) => {fs.readFile('./2.txt', 'utf8', (err, result) => {resolve(result)
        })
    });
}

function p3 () {return new Promise ((resolve, reject) => {fs.readFile('./3.txt', 'utf8', (err, result) => {resolve(result)
        })
    });
}

p1().then((r1)=> {console.log(r1);
    return p2();})
.then((r2)=> {console.log(r2);
    return p3();})
.then((r3) => {console.log(r3)
})
5.9 异步函数

异步函数是异步编程语法的终极解决方案,它能够让咱们将异步代码写成同步的模式,让代码不再有回调函数嵌套,使代码变得清晰明了。

const fn = async () => {};
async function fn () {}

async 关键字

  1. 一般函数定义前加 async 关键字 一般函数变成异步函数
  2. 异步函数默认返回 promise 对象
  3. 在异步函数外部应用 return 关键字进行后果返回 后果会被包裹的 promise 对象中 return 关键字代替了 resolve 办法
  4. 在异步函数外部应用 throw 关键字抛出程序异样
  5. 调用异步函数再链式调用 then 办法获取异步函数执行后果
  6. 调用异步函数再链式调用 catch 办法获取异步函数执行的错误信息

await 关键字

  1. await 关键字只能呈现在异步函数中
  2. await promise await 前面只能写 promise 对象 写其余类型的 API 是不不能够的
  3. await 关键字可是暂停异步函数向下执行 直到 promise 返回后果
退出移动版