兰花和桂花树

时间:2018-01-19 00:12:25来源:杰瑞文章网点击:作文字数:600字
1. JS中的异步操作哪些? 定时器settimeout for (var i = 0; i <10; i++) { setTimeout(()=>{ console.log(i); }, 0); } //=>10 //=>10 //=>10 //=>10 //=>10 //=>10 //=>10 //=>10 //=>10 //=>10 问:下面打印的结果是? console.log('1') setTimeout(()=>{console.log('2')},0) console.log('3') ------------------------ // 1 // 3 // 2 事件绑定addEventListener,onclick for (var i = 0; i < tabList.length; i++) { //tabList[i] <=>每一轮循环当前要操作的LI DOM对象 tabList[i].onclick = function () { alert(i); changeTab(i);//=>需要把当前点击的这个LI的索引传递进来 } }*/ 当绑定完毕事件后,进行点击发现i全都是3了 AJAX一般采取异步处理 promise async/await 2. 处理异步的方式有哪些? 2.1 回调函数 回调callback是一个函数被作为一个参数传递到另一个函数里,在那个函数执行完后再执行。( B函数被作为参数传递到A函数里,在A函数执行完后再执行B ) 假定有两个函数f1和f2,f2等待f1的执行结果,f1()-->f2();如果f1很耗时,可以改写f1,把f2写成f1的回调函数: function f1(callback){   setTimeout(function () {     callback(); // f1的任务代码   }, 1000); } f1(f2); // 执行 采用回调的方式,把同步操作变成了异步操作,f1不会堵塞程序运行,相当于先执行程序的主要逻辑,将耗时的操作推迟执行。 回调函数是异步编程最基本的方法,其优点是简单、容易理解和部署,缺点是不利于代码的阅读和维护,各个部分之间高度耦合,流程会很混乱,而且每个任务只能指定一个回调函数。 注意 区分 回调函数和异步,回调是实现异步的一种手段,并不一定就是异步。 回调也可以是同步,如: //下面没有任何有关异步的函数操作,所以是同步的 function A(callback){ console.log("I am A"); callback(); //调用该函数 } function B(){ console.log("I am B"); } A(B); 2.2 事件监听 采用事件驱动模式,任务的执行不取决代码的顺序,而取决于某一个事件是否发生。 监听函数有:on,bind,listen,addEventListener,observe 举例,为f1绑定一个事件(jquery写法):f1.on('done',f2);即当f1发生done事件,就执行f2。 function f1(){ settimeout(function(){ // f1的任务代码 f1.trigger('done'); // 执行完成后,立即触发done事件,从而开始执行f2 },1000); } 优点:易理解,可绑定多个事件,每一个事件可指定多个回调函数,可以去耦合,有利于实现模块化 缺点:整个程序都要变成事件驱动型,运行流程会变得不清晰 2.3 发布订阅 2.4 Promise 2.4.1 Promise基本概述 promise的三种状态pending,fulfilled,rejected,状态只能是3个中的一种 状态改变结果就定死了,不能再改变状态 resolve,reject其实就是你在声明Promise中的一道往外传递参数的门,.then()中的参数就是你从这个门往外resolve的参数,.cathch()中的参数就是你从这个门往外reject的参数 2.4.2 基本用法 new Promise时候会立刻执行 new Promise.png 控制台能反映当前promise的状态,因为我没有resolve或reject,状态就不会发生改变 new Promise((resolve,reject)=>{console.log('1')}) //=> 1 里面加入resolve我们看看他的状态 resolve.png 可以看到Promise的状态变成了resolve return new Promise return new Promise一般情况下我们把Promise封装到一个函数中,在我们需要处理异步的时候进行调用,就需要进行return操作,当我们调用函数的时候实际上是进行上面的new Promise立即执行,new promise还是同步处理的 const ajaxPromise= param => { return new Promise((resovle, reject) => { $.ajax({ ... "success": res => { resovle(res); }, "error": err => { reject(err); } }) }) } promise中return的问题 一般情况下我们只考虑一种参数状态处理的时候就不需要return,比如上面的代码块,如果进入success时,success的回调函数就只有一局resolve,而且这是最后一句话,执行完就resolve出去了,就不用进行return操作,但是如果回调的时候考虑返回值的多种状态就需要进行return,否则resolve后面的函数仍会执行 function AA(a){ return new Promise((resolve,reject)=>{ if(a==3){ console.log('resolve前面的语句') resolve('resolve的结果') console.log('resolve后面的语句') } else{ reject } }) } AA(3).then(res=>{console.log(res)}) //=>resolve前面的语句 //=>resolve后面的语句 //=>resolve的结果 return在起到中断返回的作用,但是是promise中then()的参数只能接受由resolve出去的,return的参数是无效的 function AA(a){ return new Promise((resolve,reject)=>{ if(a==3){ return '3' resolve('resolve的结果') } else{ reject } }) } AA(3).then(res=>{console.log(res)}) //=> 无反应 then的使用 then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then方法。 function AA(a){ return new Promise((resolve,reject)=>{ if(a==3){ resolve('resolve的结果') } }) } AA(3).then(res1=>{return AA(3)}) .then(res2=>{console.log(res2)}) //=> resolve的结果 只要在then中return出去的都会被包装为新的Promise实例,无论你return出去的是什么东西,并且return的值不可能return到promise外面被其他变量接收(解决办法:1.callback 2.async swait) function AA(a){ return new Promise((resolve,reject)=>{ if(a==3){ resolve('resolve的结果') } }) } AA(3).then(res=>{return '3'}) .then(res=>{console.log(res)}) //=> 3 后续链式的.then只能接受resolve到的东西,而不会一个new Promise函数 function AA(a){ return new Promise((resolve,reject)=>{ if(a==3){ resolve('resolve的结果') } }) } AA(3) .then(res=>{return AA(4)}) .then(res=>{console.log(res)}) .catch(res=>{console.log('catch ' + res)}) //=>catch 4 catch的使用 catch用于捕获reject从而达到rejected状态 .catch实际上是.then里面的第二个参数 function AA(a){ return new Promise((resolve,reject)=>{ if(a==3){ resolve('resolve的结果') } }) } AA(3) .then(res=>{return Promise.reject('在catch捕获')}) .then(res=>{console.log('then' + res)},err=>{console.log('第二个参数位置' + err)}) //=>第二个参数位置在catch捕获 若不放回调里面,cathc无法捕获是哪个位置发生的异常 function AA(a){ return new Promise((resolve,reject)=>{ if(a==3){ resolve('resolve的结果') } reject(4) }) } AA(3) .then(res=>{return AA(4)}) .then(res=>{console.log(res)}) .catch(res=>{console.log(res)}) .catch(res=>{console.log(res)}) 如果我们想要第二个catch捕获,不用async写的话只能写在回调函数里面,这是promise的缺点(轻微回调地狱) function AA(a){ return new Promise((resolve,reject)=>{ if(a==3){ resolve('resolve的结果') } reject(4) }) } AA(3) .then(res=>{ AA(4) .then(res=>{ console.log(res) }) .catch(res=>{ console.log(res) }) }) .catch(res=>{console.log(res)}) 如果涉及多种catch判别,回调现象就很严重了 distance(this.hazardInfo.hazardLatitude, this.hazardInfo.hazardLongitude)//定位打卡 .then(res => { uploadMedia(this)//上传媒体 .then(res => { // console.log(res); this.$http.post('URL', this.hazardInfo) //上传表单 .then(res => { console.log(res); uni.showToast({ icon: 'none', title: '上传成功', success() { setTimeout(() => { uni.navigateBack({ delta: 1 }); }, 2000); } }); }) .catch(err => { console.log(err); uni.showToast({ icon: 'none', title: '表单上传失败' }); }); }) .catch(() => { uni.showToast({ icon: 'none', title: '媒体上传失败' }); }); }) .catch(type => { switch (type) { case 0: uni.hideLoading(); uni.showToast({ icon: 'none', title: '当前未在距离范围,请调整你的位置!', position: 'bottom' }); break; case 1: uni.hideLoading(); uni.showToast({ icon: 'none', title: '定位失败,请开始定位权限', position: 'bottom' }); default: break; } }); } 如果写成链式调用,你会发现永远是第一个catch捕获,你可能会说,我就在一个catch里面进行res的类型判断不就行了,那么我问你,如果涉及到多个AJAX的promise错误,500的错误都是一样的,你怎么进行类别的判断。如果是你自己封装的promise到可以,如果是用axios这种第三方库是肯定不行的。 3. async/await 由上面可以总结Promise有两个缺点 涉及多种catch类型捕获,需要写到回调函数里面,如果链式写法会永远被第一个catch捕获 then里面的值无法return出去,只能被下一个then进行操作 3.1 async async函数永远返回的是promise对象,对,这种机制很像promise中then返回出去的东西,他只能是一个promise对象,无论你返回的是什么 async function testAsy(){ return 'hello world'; } let result = testAsy(); console.log(result) promise状态.png 那么意味着可以对result进行 then操作 async function testAsy(){ return 'hello world'; } let result = testAsy(); result.then(res=>{console.log(res)}) //=> hello world catch操作 async function testAsy(){ return Promise.reject('error') } let result = testAsy(); result .then(res=>{console.log(res)}) .catch(res=>{console.log(res)}) //=>error 所以当没有await语句执行async函数,它就会立即执行,返回一个Promise对象,非阻塞,与普通的Promise对象函数一致 3.2 await await如果等待的是Promise对象,则返回Promise的处理结果;如果是其他值,则返回该值本身await并不会进行等待。并且await会暂停当前async function的执行,等待Promise的处理完成。 await可以把primise返回的值给指定变量这是Promise语法无法实现的 如果await等的是Promise function testAsy(x){ return new Promise(resolve=>{setTimeout(() => { resolve(x); }, 3000) } ) } async function testAwt(){ let result = await testAsy('hello world'); console.log(result); console.log('tangj') } testAwt(); console.log('tangSir') //=>tangSir //=>3秒钟之后出现hello world //=>tangj 如果await等的是其他值 await等待是是其他的值,那么个同步任务没有区别 function testAsy(x){ return new Promise(resolve=>{setTimeout(() => { resolve(x); }, 3000) } ) } async function testAwt(){ let result = await 'no Promise'; console.log(result); let res = await testAsy('promise'); console.log(result); // 3秒钟之后出现hello world console.log(res ) console.log('tangj') // 3秒钟之后出现tangj } testAwt(); console.log('tangSir') //立即输出tangSir //=>tangSir //=>no Promised //=>3秒钟之后出现no Promise //=>promise //=>tangj await缺点:是只能接受resolve的结果,无法处理catch的结果,但是会对reject进行报错,从而影响async函数的继续执行 function testAsy(x) { return new Promise((resolve,reject) => { if (x == 1) { resolve('1') return } reject(2) }) } async function testAwt(){ let res = await testAsy(2) console.log(res ) console.log(3) } testAwt() 报错 不会打印下面的res和3.png 如果不想影响后面异步的进行(比如进入web首页,多页面迸发ajax,不能让其中一个错误的AJAX影响后面的AJAX请求),以下有两种操作 try catch .catch 下面我只对.catch进行说明,try catch在我看来反而还不如promise美观 function testAsy(x) { return new Promise((resolve,reject) => { if (x == 1) { resolve('1') return } reject(2) }) } async function testAwt(){ let res = await testAsy(2).catch(err=>{console.log(err)}) console.log(res ) console.log(3) } testAwt() //=> 2 //=> undefined //=> 3 那么我上面的promise嵌套回调就可以进行下面的写法 async start(){ let location = await distance(this.hazardInfo.hazardLatitude, this.hazardInfo.hazardLongitude) let meida = await uploadMedia() let form = await this.$http.post('URL', this.hazardInfo) } 记得把原来的各种catch处理放到封装的promise函数的reject之前就行了 如果我们想既要catch异常,又不想继续往下执行,有两种办法 解构赋值,适用于promise返回的为对象 let { data } = await this.$http.post('/api', { username: username, password: password }}).catch(err => { this.isRotate = false; }); console.log(data) console.log('1') //=>TypeError: undefined is not an object (evaluating '_ref.data') 无法解构导致报错,无法往下进行 用普通变量接promise返回值,适用于任何类型的返回值 let data = await this.$http.post('/api, { username: this.username, password: this.password }}).catch(err => { this.isRotate = false; }); console.log(data) console.log('1') if(data == undefined ) return console.log('2') //=>undefined //=>1
作文投稿

兰花和桂花树一文由杰瑞文章网免费提供,本站为公益性作文网站,此作文为网上收集或网友提供,版权归原作者所有,如果侵犯了您的权益,请及时与我们联系,我们会立即删除!

杰瑞文章网友情提示:请不要直接抄作文用来交作业。你可以学习、借鉴、期待你写出更好的作文。

兰花和桂花树相关的作文:

    无相关信息

说说你对这篇作文的看法吧