/*****************************/
//19、promisify
//promise可以解决的问题:
//1、回调嵌套的问题 .then.then
//2、可以同步多个异步请求的结果
function read()
{
return new Promise((resolve,reject)=>{
fs.readFile(name.txt,data,function(err,data){
if(err)reject(err);
resolve(data);
})
})
}
function write()
{
return new Promise((resolve,reject)=>{
fs.readFile(name.txt,data,function(err,data){
if(err)reject(err);
resolve(data);
})
})
}
/**我没有打印出结果*/
const fs = require("fs").promises;
const util = require('util');
let read = util.promisify(fs.readFile);
let write = util.promisify(fs.writeFile);
read('name.txt','utf8').then((data)=>{
console.log(data);
})
/*********************/
//将node的api快速的转换成promise的形式
//fs.readFile()
const fs = require('fs');
const promisify = fn=>(...args)=>{
return new Promise((resolve,reject)=>{
fn(...args,function(err,data){
if(err)reject(err);
resolve(data);
})
})
}
/*另一种写法
const promisify = function(fn){
return function(...args){
return new Promise((resolve,reject)=>{
fn(...args,function(err,data){
if(err)reject(err);
resolve(data);
})
})
}
}
*/
let read = promisify(fs.readFile);
read('name.txt','utf8').then((data)=>{
console.log(data);
})
/*****************************/
//20、promise-all
const fs = require('fs').promises;
//将node的api快速的转换成promise的形式
const isPromise = value => typeof value.then === 'function';
Promise.all = function(promises){ //全部成功才成功
return new Promise((resolve,reject)=>{
//遍历数组,一次拿到执行结果
let arr = [];
let index = 0;
const processData = (key,data)=>{
arr[key]=data;
//不能使用数组的长度来计算(执行顺序不一致,可能会造成[undefined,undefine,1]的结果)
if(++index === promises.length)
{
resolve(arr);
}
};
for(let i=0; i <promises.length; i++)
{
let result = promises[i];
if(isPromise(result))
{
result.then((data)=>{
processData(i,data);
},reject);
}
else
{
processData(i,result);
}
}
});
}
Promise.all([fs.readFile('name.txt','utf8'),fs.readFile('age.txt','utf8')]).then(data=>{
console.log(data);
}).catch(err=>console.log(err));
//promise缺陷默认无法中断,只是不采用返回的结果, fetch api
//
//异步:并发(使用for循环迭代执行)和串行(借助回调,第一个完成后调用第二个)
//21、promise race
const fs = require('fs').promises;
const isPromise = value => typeof value.then === 'function';
Promise.race = function(promises){
return new Promise((resolve,reject)=>{
for(let i = 0; i < promises.length; i++)
{
let result = promises[i];
if(isPromise(result)){
result.then(resolve,reject);
}
else
{
resolve(result);
}
}
});
}
//赛跑 谁跑的快用谁的(多个接口请求,我希望采用快的那个)
/*
Promise.race([fs.readFile('name.txt','utf8'),fs.readFile('age.txt','utf8')]).then(data=>{
console.log(data);
}).catch(err=>console.log(err));
*/
//中断promise 一个promise正在走向成功 3000之后成功,如果超过2s就认为失败了
let promise = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('ok 成功了');
},3000);
});
const wrap = promise =>{
let abort;
let myP = new Promise((resolve,reject)=>{
abort = reject;
});
let p = Promise.race([promise,myP]);
p.abort = abort;
return p;
}
let p = wrap(promise);
p.then(data=>{
console.log(data);
},(err)=>{
console.log("失败了",err);
})
setTimeout(()=>{
p.abort('promise 超时');//中断请求
},2000)
//22、中断promise链
Promise.resolve(100).then().then(()=>{
return new Promise((resolve,reject)=>{});
}).then(data=>{
console.log(data);
},err=>{
console.log(err);
});
//什么都打印不出来,promise处于pending状态
Promise.resolve(100).then().then(()=>{
return function(){};
}).then(data=>{
console.log(data);
},err=>{
console.log(err);
});
//[Function (anonymous)]即使返回的是空函数,也会向下传递
//23、generator的使用
//co库
//generator.js
//generator生成器=》遍历器(需要有一个next方法)=>数组=》类数组(长得像数组)
//原理就是遍历这个对象,将结果放到数组中,这个数据必须有个遍历器。[...new Set()] for of
const likeArray = {0:'a',1:'b',2:'c',3:'d',length:4};
console.log([...likeArray]); //报错likeArray is not iterable
//将类数组转成数组 Array.from(likeArray);
const likeArray = {0:'a',1:'b',2:'c',3:'d',length:4};
console.log(Array.from(likeArray));//["a", "b", "c", "d"]
const likeArray = {0:'a',1:'b',2:'c',3:'d',length:4};
likeArray[Symbol.iterator]=function(){
let i = 0;
return { //遍历器
next:()=>{ //使用箭头函数确保this不变化
return {value:this[i],done:i++ === this.length}
}
}
}
console.log([...likeArray]);
//["a", "b", "c", "d"]
//换成generator实现:
//"元编程" 自己改写js 原因的功能
const likeArray = {0:'a',1:'b',2:'c',3:'d',length:4};
likeArray[Symbol.iterator] = function *(){ //generator函数可以生产遍历器
let i=0;
while(i !== this.length)
{
yield this[i++];
}
}
console.log([...likeArray]); //["a", "b", "c", "d"]
//一旦遇到 yield 表达式,生成器的代码将被暂停运行,直到生成器的 next() 方法被调用。
//普通函数默认会从头到尾执行没有暂停的功能
//generator函数是es6提供的语法,如果碰到yield就会“暂停”执行(redux-sage,koa1中)
function * read(){
yield 1;
yield 2;
yield 3;
return undefined;
}
let it = read();
console.log(it.next()); //{value: 1, done: false}
console.log(it.next()); //{value: 2, done: false}
console.log(it.next()); //{value: 3, done: false}
console.log(it.next()); //{value: undefined, done: true}
function * read(){
yield 1;
yield 2;
yield 3;
return undefined;
}
let it = read(); //it就是迭代器,迭代器上有个next方法
console.dir(it);
/*************/
function * read(){
yield 1;
yield 2;
yield 3;
return undefined;
}
let it = read();
let flag = false;
do{
let {value,done} = it.next();
console.log(value);
flag = done;
}while(!flag);
/**************/
//蛇形执行,除了第一次之外的next()方法,都是把next中的参数传递给上一次yield的返回结果
function * read(){
let a = yield 1;
console.log('a=',a);
let b = yield 2;
console.log('b=',b);
let c = yield 3;
console.log('c=',c);
return c;
}
let it = read();
it.next(); //第一次的next传递参数没有任何意义
it.next('2');
it.next('3');
//a= 2
//b= 3
/*************************/
name.txt:age.txt
age.txt:10
const fs = require('fs').promises;
function * read() //代码编写更像是同步的(执行还是异步的)
{
let name = yield fs.readFile('name.txt','utf8');
let age = yield fs.readFile('age.txt','utf8'); //async await
return age;
}
//read().then(data=>{
//console.log(data);
//})
//优化这段代码
let it = read();
let {value,done} = it.next();
console.log(1,value,done);
value.then(data=>{
console.log(2,data);
let {value,done} = it.next(data);
console.log(3,value,done);
value.then(data=>{
let {value,done} = it.next(data);
console.log(4,value);
})
})
//1 Promise { <pending> } false
//2 age.txt
//3 Promise { <pending> } false
//4 10
/****************/
const fs = require('fs').promises;
function * read(){
try{
let name = yield fs.readFile('name.txt','utf8');
let age = yield fs.readFile('age.txt','utf8');
return age;
}catch(e)
{
console.log(e);
}
}
let it = read();
let {value, done} = it.next();
console.log(1,value,done);
value.then(data=>{
let {value,done} = it.next(data);
console.log(2,value,done);
value.then(data=>{
it.throw('error');
console.log(3);
})
})
//1 Promise { <pending> } false
//2 Promise { <pending> } false
//error
//3
//24、co库的实现
const fs = require('fs').promises;
function * read(){
let name = yield fs.readFile('name.txt','utf8');
let age = yield fs.readFile('age.txt','utf8');
return age;
}
const co = it =>{
return new Promise((resolve,reject)=>{
//异步迭代靠的是回调函数
function next(data)
{
let {value,done} = it.next(data);
if(!done){
Promise.resolve(value).then(data=>{
console.log(data,done);
next(data);
},reject);
}else{
resolve(value);
}
}
next();
})
}
co(read()).then(data=>{
console.log(data);
})
//age.txt false
//10 false
//10
const fs = require('fs').promises;
function * read(){
let name = yield fs.readFile('name.txt','utf8');
let age = yield fs.readFile('age.txt','utf8');
return age;
}
const co = it =>{
return new Promise((resolve,reject)=>{
//异步迭代靠的是回调函数
function next(data)
{
let {value,done} = it.next(data);
if(!done){
Promise.resolve(value).then(next,reject);
}else{
resolve(value);
}
}
next();
})
}
co(read()).then(data=>{
console.log(data);
})
//10
//async + await = generator + co
//async await 替换到了 generator 和 co 默认async函数执行后返回的就是一个promise
const fs = require('fs').promises;
async function read(){
let name = await fs.readFile('name.txt','utf8');
let age = await fs.readFile('age.txt','utf8');
return age;
}
read().then(data=>{
console.log(data);
})
//10
//25、eventloop执行顺序
//微任务执行完->GUI渲染页面->取出一个宏任务执行
/*
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script type="text/javascript">
document.body.style.background = 'green';
console.log(1);
Promise.resolve().then(()=>{
console.log(2);
document.body.style.background = 'red';
});
console.log(3);
//1 3 2 'red'
</script>
</body>
</html>
*/
/*
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script type="text/javascript">
document.body.style.background = 'green';
console.log(1);
setTimeout(()=>{
document.body.style.background = 'red';
},0);
console.log(3);
//1 3 由green变成red
</script>
</body>
</html>
*/
//进程是计算机调度的基本单位
//进程中包含着线程
//26、eventloop的执行顺序
//es6内部是一个微任务
/*
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script type="text/javascript">
Promise.resolve().then(()=>{
console.log('Promise');
setTimeout(()=>{
console.log('setTimeout2');
},0);
})
setTimeout(()=>{
console.log('setTimeout');
Promise.resolve().then(()=>{
console.log('Promise2');
})
},0);
//Promise
//setTimeout
//Promise2
//setTimeout2
</script>
</body>
</html>
*/