node(19-25)

    技术2025-06-06  77

    /*****************************/ //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> */

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    Processed: 0.011, SQL: 9