缘起

没理解js异步的同学看下面的例子:

for (var i = 0; i < 5; i++) {
  //模拟一个异步操作
setTimeout(() => {
console.log(i);
}, 1000);
}

我们想要的结果是:0,1,2,3,4

结果却出乎意料:5,5,5,5,5

分析

js的特点就是单线程异步非堵塞。需要好好理解这句话:js对于异步操作,不会停下来等待上一个异步操作完成,才进行下一个异步操作。

如果要达到顺序执行,只能用回调:也就是上一个异步操作完成时,再调用下一个异步操作。

要是如上面的循环,要如何操作呢?

解决方法1

通过调用自身解决循环的回调嵌套问题

function sync(i) {
setTimeout(() => {
if (i < 5){
console.log(i);
i++;
sync(i);
}
}, 1000);
} sync(0)

解决方法2

使用await/async

优点:直观,符合同步编程思维。其实本质还是异步回调

缺点:大部分浏览器下载还不支持。需要配合Promise使用,需要写成两个函数

服务器端node.js支持。以下代码在最新版chrome浏览器中可以运行:

const f = (i) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(i);
}, 1000);
});
}; const testAsync = async () => {
for (var i = 0; i < 5; i++) {
const t = await f(i);
console.log(t);
}
}; testAsync();

解决方法3

使用co

function* useco(){
for(var i=0; i<5; i++){
yield new Promise((resolve, reject) => {
setTimeout(() => {
resolve(i);
console.log(i);
}, 1000);
});
}
} co(useco);

依赖于上一个异步操作的结果,进行下一个异步操作:

function* useco() {
var x=0;
for (var i = 0; i < 5; i++) {
x= yield new Promise((resolve, reject) => {
setTimeout(() => {
resolve(x+i);
}, 1000);
});
console.log(x);
}
}
co(useco).then(() => {
   console.log('执行完毕');
})
 

co还是很强大的。

解决方法4

等待补充...

最新文章

  1. 菜鸟学Linux命令:lsof命令 查找指定用户、进程、端口打开的文件
  2. Nginx开启gzip压缩功能
  3. 【Mysql】命令行
  4. 2015-09-22CSS:border、background、表格、超链接、overflow、firebug
  5. Ionic集成ArcGIS JavaScript API.md
  6. 在block内如何修改block外部变量
  7. sql中count(*)、count(col)、count(1)区别
  8. 出现“Unable to resolve target &#39;android-XXX&#39;”怎么处理?
  9. 服务器四:多进程epoll
  10. 学习django就看这本书了!django book 2.0中文版
  11. linux和windows下icmp的区别
  12. if __name__ == &#39;main&#39;: 的作用和原理
  13. Jmeter获取redis数据
  14. Android数据存储:File
  15. 20155302《网络对抗》Exp6 信息收集与漏洞扫描
  16. Android 软键盘弹出与关闭监听
  17. 【转】手机web前端调试页面的几种方式
  18. Java生成唯一GUID
  19. Katalon Studio简单使用(一)
  20. WCF学习之三, 寄宿方式 代码,配置文件

热门文章

  1. odoo开发笔记 -- 权限机制
  2. 十分钟内在Ubuntu系统上搭建Mono开发环境(Mono软件Ubuntu系统国内镜像源、Mono国内镜像源)
  3. CentOS7下搭建FastDfs(V5.11)+Keepalived分布式集群部署
  4. 分享一套简单的CodeSmith三层模板
  5. 解决tomcat使用时catalina.out过大的问题
  6. 详解C#特性和反射(三)
  7. 第三方登录:微信扫码登录(OAuth2.0)
  8. [转]Magento刷新索引的几种方法
  9. SQL语句大全从基础到熟练(不含数据库高端操作)日常用户 三、
  10. 数据库中存储日期的字段类型到底应该用varchar还是datetime