js中的异步与同步,解决由异步引起的问题
之前在项目中遇到过好多次因为异步引起的变量没有值,所以意识到了认识js中同步与异步机制的重要性
在单线程的js中,异步代码会被放入一个事件队列,等到所有其他代码执行后再执行,而不会阻塞线程。
下面是js几种最常见的异步情况:
- 异步函数 setTimeout和setInterval
异步函数,如setTimeout和setInterval,被压入了称之为Event Loop的队列。
setTimeout:在指定的毫秒数后,将定时任务处理的函数添加到执行队列的队尾。所以有时候也可以使用setTimeout解决异步带来的问题
setInterval:按照指定的周期(以毫秒数计时),将定时任务处理函数添加到执行队列的队尾。
Event Loop是一个回调函数队列。当异步函数执行时,回调函数会被压入这个队列。JavaScript引擎直到异步函数执行完成后,才会开始处理事件循环。这意味着JavaScript代码不是多线程的,即使表现的行为相似。事件循环是一个先进先出(FIFO)队列,这说明回调是按照它们被加入队列的顺序执行的。 - ajax
- node.js中的许多函数也是异步的
解决由的js异步引起的问题办法:
- 命名函数
清除嵌套回调的一个便捷的解决方案是简单的避免双层以上的嵌套。传递一个命名函数给作为回调参数,而不是传递匿名函数
例:var fromLatLng, toLatLng;
var routeDone = function( e ){
console.log( "ANNNND FINALLY here's the directions..." );
// do something with e
};
var toAddressDone = function( results, status ) {
if ( status == "OK" ) {
toLatLng = results[0].geometry.location;
map.getRoutes({
origin: [ fromLatLng.lat(), fromLatLng.lng() ],
destination: [ toLatLng.lat(), toLatLng.lng() ],
travelMode: "driving",
unitSystem: "imperial",
callback: routeDone
});
}
};
var fromAddressDone = function( results, status ) {
if ( status == "OK" ) {
fromLatLng = results[0].geometry.location;
GMaps.geocode({
address: toAddress,
callback: toAddressDone
});
}
};
GMaps.geocode({
address: fromAddress,
callback: fromAddressDone
});async.js 库可以帮助我们处理多重Ajax requests/responses,如:
async.parallel([
function( done ) {
GMaps.geocode({
address: toAddress,
callback: function( result ) {
done( null, result );
}
});
},
function( done ) {
GMaps.geocode({
address: fromAddress,
callback: function( result ) {
done( null, result );
}
});
}
], function( errors, results ) {
getRoute( results[0], results[1] );
}); - 使用promise
promise在异步执行的流程中,把执行代码和处理结果的代码清晰地分离了:
promise还可以做若干个异步的任务,例:有一个异步任务,需要先做任务1,如果任务成功后再做任务2,任何任务失败则不再继续并执行错误处理函数。
job1.then(job2).then(job3).catch(handleError); //
job1
、job2
和job3
都是Promise对象例:
'use strict'; var logging = document.getElementById('test-promise2-log');
while (logging.children.length > 1) {
logging.removeChild(logging.children[logging.children.length - 1]);
} function log(s) {
var p = document.createElement('p');
p.innerHTML = s;
logging.appendChild(p);
}
// 0.5秒后返回input*input的计算结果:
function multiply(input) {
return new Promise(function (resolve, reject) {
log('calculating ' + input + ' x ' + input + '...');
setTimeout(resolve, 500, input * input);
});
} // 0.5秒后返回input+input的计算结果:
function add(input) {
return new Promise(function (resolve, reject) {
log('calculating ' + input + ' + ' + input + '...');
setTimeout(resolve, 500, input + input);
});
} var p = new Promise(function (resolve, reject) {
log('start new Promise...');
resolve(123);
}); p.then(multiply)
.then(add)
.then(multiply)
.then(add)
.then(function (result) {
log('Got value: ' + result);
});关于promise的两个方法
var p1 = new Promise(function (resolve, reject) {
setTimeout(resolve, 500, 'P1');
});
var p2 = new Promise(function (resolve, reject) {
setTimeout(resolve, 600, 'P2');
});
// 同时执行p1和p2,并在它们都完成后执行then:
Promise.all([p1, p2]).then(function (results) {
console.log(results); // 获得一个Array: ['P1', 'P2']
});var p1 = new Promise(function (resolve, reject) {
setTimeout(resolve, 500, 'P1');
});
var p2 = new Promise(function (resolve, reject) {
setTimeout(resolve, 600, 'P2');
});
Promise.race([p1, p2]).then(function (result) {
console.log(result); // 'P1'
});
//由于p1
执行较快,Promise的then()
将获得结果'P1'
。p2
仍在继续执行,但执行结果将被丢弃。
本文参考:
http://blog.csdn.net/u013063153/article/details/52457307
js中的异步与同步,解决由异步引起的问题的更多相关文章
- js中style.display=""无效的解决方法
本文实例讲述了js中style.display=""无效的解决方法.分享给大家供大家参考.具体解决方法如下: 一.问题描述: 在js中我们有时想动态的控制一个div显示或隐藏或更多 ...
- Python并发编程06 /阻塞、异步调用/同步调用、异步回调函数、线程queue、事件event、协程
Python并发编程06 /阻塞.异步调用/同步调用.异步回调函数.线程queue.事件event.协程 目录 Python并发编程06 /阻塞.异步调用/同步调用.异步回调函数.线程queue.事件 ...
- 深入理解 JS 引擎执行机制(同步执行、异步执行以及同步中的异步执行)
首先明确两点: 1.JS 执行机制是单线程. 2.JS的Event loop是JS的执行机制,深入了解Event loop,就等于深入了解JS引擎的执行. 单线程执行带来什么问题? 在JS执行中都是单 ...
- JS中for循环变量作用域--解决for循环异步执行的问题
被这个问题困惑了很久,终于在网上找到了答案,感谢~ 现在分享给大家~ js中如何让一个for循环走完之后,再去执行下面的语句? 这涉及for循环变量作用域的问题,js中作用域只有函数作用域和全局作用域 ...
- js文件引用方式及其同步执行与异步执行
详见: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp74 任何以appendChild(scriptNode) 的方式引入 ...
- js中奇怪的问题 同步ajax,modal遮罩层
奇怪问题一 今天有一段js执行的时候出现了问题 $.ajax({ ..., async:false, ... }); $('#myModal').modal('hide'); loadcurrentp ...
- UML建模中简单消息、同步消息和异步消息
两种消息在UML图中的表示方法如图: 1.同步方式 两个通信应用服务之间必须要进行同步,两个服务之间必须都是正常运行的.发送程序和接收程序都必须一直处于运行状态,并且随时做好相互通信的准备. 发送程序 ...
- js中toFixed精度问题的解决办法
toFixed() 方法可把 Number 四舍五入为指定小数位数的数字.例如将数据Num保留2位小数,则表示为:toFixed(Num):但是其四舍五入的规则与数学中的规则不同,使用的是银行家舍入规 ...
- JS中多个onload冲突解决办法
一 多个window.onload冲突 在一个页面中有两个JavaScript 分别都用到了window.onload一个是:window.onload=externallinks,另一个是:win ...
- 记录js中的兼容问题及解决办法
1.获取非行内样式的兼容问题: 2.获取事件对象的兼容问题: 3.事件冒泡的兼容: 4.keyCode的兼容问题: 5.处理默认事件的兼容问题: 6.事件的绑定兼容问题:
随机推荐
- Exception in thread "main" java.lang.StackOverflowError at java.util.ArrayList$SubList.rangeCheckForAdd(Unknown Source)
Exception in thread "main" java.lang.StackOverflowError at java.util.ArrayList$SubList.ran ...
- JSOUP 打开url的方式
一般采用这种方式: try{ doc = Jsoup.connect(url) .header("User-Agent", "Mozilla/5.0 (Windows N ...
- Python 和 Scikit-Learn
Reference:http://mp.weixin.qq.com/s?src=3×tamp=1474985436&ver=1&signature=at24GKibw ...
- 基于R语言的时间序列指数模型
时间序列: (或称动态数列)是指将同一统计指标的数值按其发生的时间先后顺序排列而成的数列.时间序列分析的主要目的是根据已有的历史数据对未来进行预测.(百度百科) 主要考虑的因素: 1.长期趋势(Lon ...
- 分析轮子(四)- 我也玩一把 Serializable.java
前言:在写 分析轮子(一)-ArrayList.java 的时候曾经下过一个结论 “实现Serializable接口,表示ArrayList是可序列化的”,这个结论是以往学习的经验所得,并且平时在编程 ...
- C#语法——泛型的多种应用 C#语法——await与async的正确打开方式 C#线程安全使用(五) C#语法——元组类型 好好耕耘 redis和memcached的区别
C#语法——泛型的多种应用 本篇文章主要介绍泛型的应用. 泛型是.NET Framework 2.0 版类库就已经提供的语法,主要用于提高代码的可重用性.类型安全性和效率. 泛型的定义 下面定义了 ...
- C#获取中国天气网免费天气预报信息
中国天气网接口地址:”http://wthrcdn.etouch.cn/WeatherApi?citykey=” + weatherCityCode(为城市code); 下面是转化过程中我们需要用到的 ...
- 每天学习一个Linux命令-目录
在工作中总会零零散散使用到各种Linux命令,从今天开始详细的学习一下linux常用命令,坚持每天一个命令,学习的主要参考资料为: 1.竹子-博客(https://www.cnblogs.com/pe ...
- js cookie跨域设置
/** * 设置cookie方法 * @param {string} c_name cookie键值 * @param {string} value cookie值 * @param {Boolean ...
- Win7 SP1 32位 旗舰版 IE8 快速稳定 纯净优化 无人值守 自动激活 20170518
一.系统特色 1.采用微软原版旗舰版定制而成. 2.优化系统服务,关闭一些平时很少使用的服务. 3.精简掉一些无用的东西. 4.系统全程离线制作,不包含任何恶意插件,放心使用. 5.右下角时间加上星期 ...