前端分享----JS异步编程+ES6箭头函数
前端分享----JS异步编程+ES6箭头函数
##概述Javascript语言的执行环境是"单线程"(single thread)。所谓"单线程",就是指一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务。
这种模式的好处是实现起来比较简单,执行环境相对单纯;坏处是只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。常见的浏览器无响应(假死),往往就是因为某一段Javascript代码长时间运行(比如死循环),导致整个页面卡在这个地方,其他任务无法执行。
JavaScript语言本身并不慢,慢的是读写外部数据,比如等待Ajax请求返回结果。这个时候,如果对方服务器迟迟没有响应,或者网络不通畅,就会导致脚本的长时间停滞。
为了解决这个问题,Javascript语言将任务的执行模式分成两种:同步(Synchronous)和异步(Asynchronous)。"同步模式"就是传统做法,后一个任务等待前一个任务结束,然后再执行,程序的执行顺序与任务的排列顺序是一致的、同步的。这往往用于一些简单的、快速的、不涉及读写的操作。
"异步模式"则完全不同,每一个任务分成两段,第一段代码包含对外部数据的请求,第二段代码被写成一个回调函数,包含了对外部数据的处理。第一段代码执行完,不是立刻执行第二段代码,而是将程序的执行权交给第二个任务。等到外部数据返回了,再由系统通知执行第二段代码。所以,程序的执行顺序与任务的排列顺序是不一致的、异步的。
以下总结了"异步模式"编程的几种方法,理解它们可以让你写出结构更合理、性能更出色、维护更方便的JavaScript程序。##实际应用场景在项目的编辑页面,有很多时候会出现下拉,并且下拉框是通过请求后台获取的数据,但是会出现一种情况大家可能有遇到过,就是下拉框回填不成功,可能大家已经都清楚了原因就是因为:当请求的详情信息还没返回,请求的下拉接口却已经先返回来了,说直白一点,就是程序的执行先后顺序问题。那么怎么解决这种问题呢?##常见的解决方案###1.用延时来推测结果大概什么时候!
var result=ajax(url);
setTimeout(function(result){
console.log(result);
},400);
优点:几乎无弊端:尽量可能设置长时间延时,否则,我们将会操作一个undefined的result,可以说这是一种最不推荐并且反对的写法###2.回调函数!js最常见的一种规定程序执行的先后顺序的处理就是采用回调函数,可能java的同学不是很明白,其实很多地方都应用到了,比如:ajax的成功之后调用success方法,失败调用error方法,这种就叫回调函数,在某个时间点,数据返回来了,就执行。所以,通常遇到实际场景就会采用回调函数的写法,把第二个ajax写在第一个ajax的success里面,等第一个ajax请求返回结果后,在执行第二个。这种方法俗称函数嵌套。能解决这种情况。但是既然叫函数嵌套,嵌套二字难免让人感觉冗余,没错。
ajax(url0,function(result0){
ajax(result0.url1,function(result1){
ajax(result1.url2,function(result2){
console.log(result2);
});
});
});
如果嵌套有3个甚至更多,那就出现了回调地狱(Callback Hell)问题。如何规避这种问题呢?答案是就是:promise/a+规范,下面我们看一下promise/a+规范在了解promise之前我们先来了解一个链式写法;##链式写法链式写法也是我们在使用jQuery时候常见的一种,
$('#tab').eq($(this).index()).show().siblings().hide();
没错,这个就是我们所谓的链式写法,只是大家不知道书名而已;之所以叫链式写法,不难看出我们在一个元素上做的所有jQuery处理都可以一直 "." 下去, 为什么能这样,因为jQuery源码封装的时候,每个方法都返回this(jQuery)。
var obj = {
step1:function(){
console.log('a');
return this;
},
step2:function(){
console.log('b');
return this;
},
step3:function(){
console.log('c');
return this;
},
step4:function(){
console.log('d');
return this;
}
}
console.log('-----\n');
obj.step1().step2().step3();
console.log('-----\n');
obj.step4().step2().step1();
执行结果复制到控制台查看。这样的写法是不是看着很爽,那么与我们要讲的promise有什么关系呢?下面进入主题PromiseES 6中原生提供了Promise对象,Promise对象代表了某个未来才会知道结果的事件(一般是一个异步操作),并且这个事件对外提供了统一的API,可供进一步处理。Promise对象有三种状态,分别是pending-进行中、resolved-已完成、rejected-已失败当Promise的状态由pending转变为resolved或rejected时,会执行相应的方法,并且状态一旦改变,就无法再次改变状态,这也是它名字promise-承诺的由来。Promise的构造函数接受一个函数作为参数,这个函数的两个参数分别是resolve方法和reject方法。如果异步操作成功,就是用resolve方法将Promise对象的状态从“未完成”变为“完成”(即从pending变为resolved),如果异步操作出错,则是用reject方法把Promise对象的状态从“未完成”变为“失败”(即从pending变为rejected)
###Promise.prototype.then()Promise的then方法返回的是一个新的Promise对象,所以这样呢,我们就能链式操作了,同时then方法它包含两个参数方法,分别是已成功resolved的回调和已失败rejected的回调,分别是状态看一个例子吧!
const p = function(){
let num = Math.random();
return new Promise((resolve, reject) => {
setTimeout(() => {
num > 0.1 ? resolve(num) : reject(num);
}, 1000);
})
};
const p1 = function(val){
let num = Math.random();
return new Promise((resolve, reject) => {
setTimeout(() => {
num > 0.01 ? resolve(num) : reject(num);
}, 1000);
})
};
p().then(val => {
console.info(`Status1:fulfilled, value1:${val}`);
return p1(val);
}, val => {
console.info(`Status1:reject,value1:${val}`);
}).then(val => {
console.info(`Status2:fulfilled, value2:${val}`);
},
/*function(val1){console.log(val1); },*/val => {
console.info(`Status2:reject,value2:${val}`);
})
那么每个then方法都要写一个成功的方法和失败的方法貌似有点冗余啊,还好,Promise提供了一个catch()方法,.catch()的作用是捕获Promise的错误,与then()的rejected回调作用几乎一致,由于Promise的抛错具有冒泡性质,能够不断传递,这样就能够在下一个catch()中统一处理这些错误。同时catch()也能够捕获then()中抛出的错误,所以建议不要使用then()的rejected回调,而是统一使用catch()来处理错误。所以上面代码改为
p().then(val => {
console.info(`Status1:fulfilled, value1:${val}`);
return p1(val);
}).then(val => {
console.info(`Status2:fulfilled, value2:${val}`);
}).catch(function(err) {
console.log('出错:' + err); // 出错:reject // 最后的catch()方法可以捕获在这一条Promise链上的异常
})
好了!你们下来可以试着去这样用用Promise。
##ES6箭头函数一个常见的问题是,ECMAScript 和 JavaScript 到底是什么关系?不是很重要,所以直白一点,ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现。而ES6,就是ECMAScript的一个版本而已,于2015年发布第一版。
1.具有一个参数的简单函数
var f = v => v;
//上面的箭头函数等同于:
var f = function(v) {
return v;
};
2.没有参数的需要用在箭头前加上小括号
//如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分。
var f = () => 5;
// 等同于
var f = function () { return 5 };
3.多个参数需要用到小括号,参数间逗号间隔,例如两个数字相加
//如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分。
var sum = (num1, num2) => num1 + num2;
// 等同于
var sum = function(num1, num2) {
return num1 + num2;
};
4.函数体多条语句需要用到大括号
var add = (a, b) => {
if (typeof a == 'number' && typeof b == 'number') {
return a + b
} else {
return 0
}
}
5.返回对象时需要用小括号包起来,因为大括号被占用解释为代码块了
var getHash = arr => {({
name: 'Jack',
age: 33
})}
再多啰嗦一个东西:解构赋值
requestLogin(loginParams).then(data => {
this.logining = false;
let { msg, code, user, list} = data;
if (!list.length) {
this.$message({
message: '登录失败',
type: 'error'
});
}
});
//等同于
requestLogin(loginParams).then(data => {
var msg=data.msg;
var list=data.list;
var code=data.code;
if (!list.length) {
this.$message({
message: '登录失败',
type: 'error'
});
}
});
是不是觉得还是比较方便简洁些了。
前端分享----JS异步编程+ES6箭头函数的更多相关文章
- JS魔法堂:深究JS异步编程模型
前言 上周5在公司作了关于JS异步编程模型的技术分享,可能是内容太干的缘故吧,最后从大家的表情看出"这条粉肠到底在说啥?"的结果:(下面是PPT的讲义,具体的PPT和示例代码在h ...
- 深究JS异步编程模型
前言 上周5在公司作了关于JS异步编程模型的技术分享,可能是内容太干的缘故吧,最后从大家的表情看出"这条粉肠到底在说啥?"的结果:(下面是PPT的讲义,具体的PPT和示例代码在h ...
- JS异步编程 (2) - Promise、Generator、async/await
JS异步编程 (2) - Promise.Generator.async/await 上篇文章我们讲了下JS异步编程的相关知识,比如什么是异步,为什么要使用异步编程以及在浏览器中JS如何实现异步的.最 ...
- JS异步编程 (1)
JS异步编程 (1) 1.1 什么叫异步 异步(async)是相对于同步(sync)而言的,很好理解. 同步就是一件事一件事的执行.只有前一个任务执行完毕,才能执行后一个任务.而异步比如: setTi ...
- js异步编程
前言 以一个煮饭的例子开始,例如有三件事,A是买菜.B是买肉.C是洗米,最终的结果是为了煮一餐饭.为了最后一餐饭,可以三件事一起做,也可以轮流做,也可能C需要最后做(等A.B做完),这三件事是相关的, ...
- 一个例子读懂 JS 异步编程: Callback / Promise / Generator / Async
JS异步编程实践理解 回顾JS异步编程方法的发展,主要有以下几种方式: Callback Promise Generator Async 需求 显示购物车商品列表的页面,用户可以勾选想要删除商品(单选 ...
- 理解js异步编程
Promise 背景 javascript语言的一大特点就是单线程,在某个特定的时刻只有特定的代码能够被执行,并阻塞其它的代码,也就是说,同一个时间只能做一件事. 怎么做到异步编程?回调函数.直到no ...
- node.js异步编程的几种模式
Node.js异步编程的几种模式 以读取文件为例: 1.callback function const fs = require('fs'); //callback function fs.readF ...
- this(ES6箭头函数里的this)
一,了解前须知 1,箭头函数:出现的作用除了让函数的书写变得很简洁,可读性很好外:最大的优点是解决了this执行环境所造成的一些问题.比如:解决了匿名函数this指向的问题(匿名函数的执行环境具有全局 ...
随机推荐
- 215. Kth Largest Element in an Array(QuickSort)
Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...
- 解决 listView gridView 与ScrollView嵌套时的冲突
package com.xqx.fight; import android.app.Activity; import android.os.Bundle; import android.view.Me ...
- UI设计:掌握这6点,轻松0到1
非科班出身能成为UI设计师吗? 答案是肯定的.世上无难事,只怕有心人.只要找对方法.坚持不懈,即便是零基础也能学好UI设计. 那么零基础学习UI设计,需要学习哪些知识?我们要从哪些地方学起?怎么系统学 ...
- 属性表格 datagridproperty
http://www.cnblogs.com/yxlblogs/p/3468921.html
- connect strings sql server
https://www.connectionstrings.com/sql-server/ Server=myServerAddress[,port];Database=myDataBase;User ...
- div 自适应宽度
div 自适应宽度 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://w ...
- 类的const成员函数,是如何改变const对象的?
我们知道类里面的const的成员函数一般是不允许改变类对象的,但是我们知道const 类型的指针是可以强制类型转出成非const指针的,同样的道理,this指针也可以被强制类型转换 class Y{ ...
- php 事务处理,ActiveMQ的发送消息,与处理消息
可以通过链式发送->处理->发送...的方式处理类似事务型业务逻辑 比如 发送一个注册消息,消息队列处理完注册以后,紧接着发送一个新手优惠券赠送,赠送完再发一个其它后续逻辑处理的消息等待后 ...
- 《沉静领导》读书笔记zz
就 像作者说的,这本书“只是一篇简单的随笔,它描绘并阐明了一种关于领导之道的思考方式,并且为把这种思考方式应用到实际行动中提供了指南.”但是,仔细想 来,倒有一点不同见解,或许,它描述的不可以叫做“领 ...
- Django入门指南-第7章:模板引擎设置(完结)
http://127.0.0.1:8000/ <!--templates/home.html--> <!DOCTYPE html> <html> <head& ...