前言:本篇主要记下生成器和Promise
一、生成器
生成器其实就是一个特殊的函数。
生成器函数
:是es6提供的一种**异步编程**解决方案,语法行为与传统函数完全不同。
异步编程
:简单来说就是纯回调函数,例如node、fs、ajax、MongoDB等
1.1生成器的声明
在函数名前面加*
//声明特殊
function * hong(){
console.log("你好,红红"); //并不会直接输出
}
//执行特殊
let iterator = hong();
terator.next(); //调用.next才会输出“你好,红红”(迭代器)
注:执行语句直接调用不会执行,要通过.next
方法去调用
1.2函数代码分隔符—yield
把函数内部分割成一段一段的
//函数代码的分隔符 yield的使用
function *lv(){
console.log(111);
yield '我分隔';
console.log(222);
yield '我分隔,到我停止';
console.log(333);
yield '我再分隔';
console.log(444);
}
let lvtor = lv();
lvtor.next(); //调用一次,输出111
lvtor.next(); //接着调用,接着输出222
lvtor.next(); //接着调用,接着输出333
//console.log(lvtor.next()); 执行获取迭代器的对象
//遍历
for(let v of lv()) {
console.log(v);
}
以上分隔结果:
遍历结果:
扫描二维码关注公众号,回复:
12449448 查看本文章
1.3 生成器函数的参数传递
next的参数作为前一个yield语句的返回值
//生成器函数的传参
function * mini(arg){
console.log(arg);
let one = yield 111;
console.log(one);
let two = yield 222;
console.log(two);
let three = yield 333;
console.log(three);
}
let itor = mini('AAA');
console.log(itor.next());
//next方法可以传入实参
console.log(itor.next('BBB')); //为yield111传入参数
console.log(itor.next('CCC'));
console.log(itor.next('DDD'));
输出结果:
1.4 生成器小例子
(1)间歇调用
1s后输出111, 然后2s后输出222 ,然后3s后输出333
//用生成器实现
function one(){
setTimeout(() => {
console.log(111);
it.next(); //使其继续执行下一个
},1000)
}
function two(){
setTimeout(() =>{
console.log(222);
it.next();
},2000)
}
function three(){
setTimeout(()=>{
console.log(333);
it.next();
},3000)
}
function * green(){
yield one();
yield two();
yield three();
}
//调用
let it = green();
it.next();
(2)模拟数据的获取
首先得先获取用户信息,再根据用户信息获取订单数据,接着再根据订单数据获取商品数据,由于他们是一层层获取的关系,所以可以用生成器来实现。
//模拟获取 用户数据 订单信息 商品数据
function getUser(){
setTimeout(()=>{
let data = '用户信息';
//调用next方法,并将数据传入
getor.next(data);
},1000)
}
function getOrder(){
setTimeout(()=>{
let data = '订单数据'
},1000)
}
function getGoods(){
setTimeout(()=>{
let data = '商品数据'
},1000)
}
//定义生成器函数
function *datas(){
yield getUser();
yield getOrder();
yield getGoods();
}
//调用生成器函数
let getor = datas();
getor.next();
- 使用到了next方法传递参数。
二、Promise
Promise是es6引入的异步编程方案。语法上Promise是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果。
- Promise构造函数:
Promise(excutor){}
Promise.prototype.then
方法Promise.prototype.catch
方法
当异步进程很多的时候,promise可以用来减少缩进。
2.1Promise的then方法的使用
- 如果状态是成功的,则调用then的第一个回调函数,否则调用第二个。
//实例化 Promise对象
const h = new Promise(function(resolve,reject){
//这里定义的两个参数一般是这两个,潜规则
setTimeout(function(){
let data = '数据读取成功啦';
resolve(data); //调用resolve,表示读取成功
//let err = '数据读取失败了'; 调用reject,表示读取失败
//reject(err);
},1000)
});
//调用promise 对象的then方法
h.then(function(value){
console.log(value); //成功时执行
},function(reason){
console.error(reason); //失败时执行
})
调用then方法,then方法的返回结果是 Promise对象,对象状态由回调函数的执行结果
决定
- 如果回调函数中返回的结果是 非 Promise类型的属性(包括没有返回值的情况undefined),状态为成功,返回值为对象的成功的值。
- 是Promise对象,则返回对象的内容
- 抛出错误
//then 方法解析
const hh = new Promise((resolve,reject) =>{
setTimeout(()=>{
resolve('红红的数据');
//reject('出错啦');
},1000)
});
const result = hh.then(value =>{
console.log(value);
//1.非Promise类型的属性
//return 'hhhhhh';
//2.是promise对象
//return new Promise((resolve,reject)=>{
//resolve('ok');
//reject('error');
//});
//3.抛出错误
throw new Error('出错了');
},reason =>{
console.warn(reason);
});
- 如果then的返回结果是Promise,则可以使用链式调用
p.then(value =>{
},reason=>{
}).then(value=>{
},reason=>{
})
2.2 用Promise封装读取文件
下面是写在名为Promise读取文件.js中:
//1.引入 fs 模块
const fs = require('fs');
//2.调用方法读取文件
// fs.readFile('./data/study.md',(err,data) =>{
//如果失败,抛出错误
// if(err) throw err;
//如果没有出错,则输出内容
// console.log(data.toString());
// })
//3.使用Promise封装
const p = new Promise(function(resolve,reject){
fs.readFile("./data/study.md",(err,data)=>{
//判断如果失败
if(err) reject(err);
//如果成功
resolve(data);
});
});
//调用then方法
p.then(function(value){
console.log(value.toString());
},function(reason){
console.log("读取失败啦!");
});
- 在控制台输入
node Promise读取文件.js
就可以查看结果了。
2.3用Promise封装ajax
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Promise封装ajax</title>
</head>
<body>
<script>
//接口地址 :https://api.apiopen.top/getJoke
const p = new Promise((resolve,reject)=>{
//封装
//1.创建对象
const xhr = new XMLHttpRequest();
//2.初始化
xhr.open("GET","https://api.apiopen.top/getJoke");
//3.发送
xhr.send();
//4.绑定事件,处理响应结果
xhr.onreadystatechange = function(){
//判断
if(xhr.readyState === 4){
//判断响应状态码200-299
if(xhr.status >= 200 && xhr.status <300){
//表示成功
resolve(xhr.response);
}else{
//如果失败
reject(xhr.status);
}
}
}
})
//指定回调 在这里做数据的处理
p.then(function(value){
console.log(value);
},function(reason){
console.log(reason);
});
</script>
</body>
</html>
2.4Promise实现多个文件内容的读取
//引入fs
const fs = require("fs");
const h = new Promise((resolve,reject)=>{
fs.readFile("./data/study.md",(err,data)=>{
resolve(data);
});
});
//调用
h.then(value =>{
return new Promise((resolve,reject)=>{
fs.readFile('./data/红红.md',(err,data)=>{
resolve([value,data]);
});
})
}).then(value => {
return new Promise((resolve,reject)=>{
fs.readFile('./data/绿绿.md',(err,data)=>{
//压入
value.push(data);
resolve(value);
});
})
}).then(value =>{
console.log(value.join('\r\n'));
});
结果:
2.5Promise的catch方法
算是then方法的语法糖,用来设置失败的回调
p.catch(function(reason){
console.warn(reason);
});