【Node100In1】01.去异步,解决掉Node.js万恶的回调陷阱
Node.js是基于事件驱动编程。异步函数随处可见,其中不乏一些常用库的方法。本例就以js中最常见的setTimeout的为例,试图改善一下回调的书写。
先来看一段伪代码:
我们实现一个需求,每隔一段时间打印一段字符串,按照一般的同步设计思维,那么大概是这个样子:
; i < ; i++) { sleep(i); printf("out:%d", i); }
但是在js中可就没这么简单了。首先,类似sleep的setTimeout函数睡眠之后的事件就在回调当中
setTimeout(function(){ },1000)
看到这我想大家也都明白了,这要是写在循环里,很难受,写起来很难受。用递归是一种方法,但是也难受。
解决这个问题的办法要借助node的两样工具:
1.Promise
2.async/await (需要node8 版本)
Promise主要用来优化回调函数的书写格式,使得多次回调的嵌套不会写那么多层。
上述循环的单次循环可以封装成如此格式:
function call_once(_i) { setTimeout(function(_i){ return ("out:"+_i) },_i*1000) }
Promise不在node官方库中 ,需要使用npm安装,Promise有很多三方包,个人比较常用的是 bluebird
npm install bluebird
const promise = require('bluebird')
对上边的call_once方法封装,就是:
function call_once(_i) { return new promise(function(resolve){ setTimeout(function(){ resolve("out:" + _i) }, _i*1000) }) }
但是这个方法也不能直接当同步方法用,回调后的内容需要写在 promise对象的then方法当中:
call_once(1).then(function(_result){ console.log(_result); })
没错,所有在这条主线上执行的内容都需要不断的用这个promise的对象then下去,写在外边是不行的。会提前执行。
所以还是没法把这个东西嵌入到for循环当中,这个时候就需要await/async了。
1.首先把所有的异步内容全部嵌套到一个异步函数当中,声明异步函数需要在function前声明关键字async。
2.在需要阻塞的函数前(这个函数需要返回promise对象)加上await关键字:
async function looper(){ for(let i = 0; i < 5; i++) { await call_once(i).then(function(_result) { console.log(_result) }) } }
如此就实现了for-sleep的方法。但是要注意,还是只限在lopper()方法当中才是同步的,写在looper外边的内容还是不行。TAT。如果是一些小功能脚本的话,就把looper当main方法用吧。
最后祝您,身体健康。再见
------------------------------------------------------>
to be continued
【Node100In1】01.去异步,解决掉Node.js万恶的回调陷阱的更多相关文章
- node.js中的回调
同步和阻塞:这两个术语可以互换使用,指的是代码的执行会在函数返回之前停止.如果某个操作阻塞,那么脚本就无法继续,这意味着必须等待. 异步和非阻塞:这两个术语可以互换使用,指的是基于回调的.允许脚本并行 ...
- node.js如何使用回调
Node.js到处使用回调,尤其在有I/O(输入/输出)操作的地方. 下面是在一个Node.js中使用filesystem模块中从磁盘上读入文件内容示例一: var fs = require('fs' ...
- Node.js标准的回调函数
Node.js标准的回调函数:第一个参数代表错误信息,第二个参数代表结果. function (err, data) 当正常读取时,err参数为null,data参数为读取到的String.当读取发生 ...
- 01慕课网《进击Node.js基础(一)》Node.js安装,创建例子
版本:偶数位为稳定版本,基数为非稳定版本 - 0.6.x - 0.7.x - 0.8.x -0.9.x -0.10.x -0.11.x 概念:Node.js采用谷歌浏览器的V8引擎,用C ...
- Node.js链式回调
由于异步的关系,代码的书写顺序可能和执行顺序并不一样,可能想先执行A再执行B,但由于异步可能B要先于A执行.例如在OC中使用AFnetworking请求数据然后刷新页面,由于网络请求是用block实现 ...
- 【解决】Node JS Error: ENOENT
The Node Beginner Book 书中的实例代码当上传图片时会报Error: ENOENT, 原因:图片默认会选择系统的缓存文件夹下,在windows下无权访问C盘,所以就报错了.. 解决 ...
- node.js异步控制流程 回调,事件,promise和async/await
写这个问题是因为最近看到一些初学者用回调用的不亦乐乎,最后代码左调来又调去很不直观. 首先上结论:推荐使用async/await或者co/yield,其次是promise,再次是事件,回调不要使用. ...
- Node.js 异步异闻录
本文首发在个人博客:http://muyunyun.cn/posts/7b9fdc87/ 提到 Node.js, 我们脑海就会浮现异步.非阻塞.单线程等关键词,进一步我们还会想到 buffer.模块机 ...
- Node.js之异步编程
> 文章原创于公众号:程序猿周先森.本平台不定时更新,喜欢我的文章,欢迎关注我的微信公众号. ![file](https://img2018.cnblogs.com/blog/830272/20 ...
随机推荐
- 关于jqGrid组件数据显示不出问题
jqGrid组件一开始怎么数据都返回了渲染不出来,查找了一天,最后发现点击搜索之后doSearch()事件触发的方法并不是数据请求接口,而是再次请求了初次登录的接口,从初次登录返回的数据,数据格式没问 ...
- 玩转postman(一)-----基础
postman的GUI界面以及各个组件介绍 主界面如下 打开postman的GUI界面以及各个元素组件介绍 分为下三部分: 1.Head navigation bar (头部导航栏):此部分有以下选项 ...
- 观察者模式C#实现实例(二)
接着上一次的话题继续. 上一篇中讲了实现思路,这篇中就直接上代码了 定义的目标接口——Isub,具体实现如下: public interface Isub { void addobser(Iobse ...
- thinkphp 响应对象
<?php namespace app\admin\controller; use think\Request; class Index{ public function index(Reque ...
- 如何解决出现AXIOS的跨域问题:Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.
转载:https://www.cnblogs.com/caimuqing/p/6733405.html 问题描述: 由于restful接口需要在头部header传递两个字段: Content-Type ...
- laraval migration 新增字段或者修改字段的方法
1.进入项目根目录执行artisan命令生成migration文件,可以指定--table和--path参数,会在对应目录下生成migration文件. php artisan make:migrat ...
- Dockerfile制作自定义镜像
本文介绍最精简的Dockerfile文件构建镜像,Docker启动的时候可以启动一个shell脚本 1.首先编写Dockerfile文件 说明 1.启动的这个shell脚本一定是不退出的,比如服务器的 ...
- 第一个VS2015 Xaramin Android项目(终)
其实还有一个问题没解决,也拖很久了.中途公司的项目太紧导致无法学习更新. 之前的问题是这样的:项目搭建成功了,App也成功发布到虚拟机.便尝试增加控件 Xaml 设计界面如下: 但是在虚拟机运行却这样 ...
- Atcoder Beginner Contest 070 D - Transit Tree Path
题意:n个点,n-1条边,组成一个无向的联通图,然后给出q和k,q次询问,每次给出两个点,问这两个点之间的最短距离但必须经过k点. 思路:我当时是用优化的Dijkstra写的(当天刚学的),求出k点到 ...
- 将 Desktop Central 与帮助台和 OS Deployer 集成
将 Desktop Central 与帮助台和 OS Deployer 集成 Desktop Central 可以与以下应用程序集成: 帮助台 OS Deployer Asset Explorer 与 ...