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万恶的回调陷阱的更多相关文章

  1. node.js中的回调

    同步和阻塞:这两个术语可以互换使用,指的是代码的执行会在函数返回之前停止.如果某个操作阻塞,那么脚本就无法继续,这意味着必须等待. 异步和非阻塞:这两个术语可以互换使用,指的是基于回调的.允许脚本并行 ...

  2. node.js如何使用回调

    Node.js到处使用回调,尤其在有I/O(输入/输出)操作的地方. 下面是在一个Node.js中使用filesystem模块中从磁盘上读入文件内容示例一: var fs = require('fs' ...

  3. Node.js标准的回调函数

    Node.js标准的回调函数:第一个参数代表错误信息,第二个参数代表结果. function (err, data) 当正常读取时,err参数为null,data参数为读取到的String.当读取发生 ...

  4. 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 ...

  5. Node.js链式回调

    由于异步的关系,代码的书写顺序可能和执行顺序并不一样,可能想先执行A再执行B,但由于异步可能B要先于A执行.例如在OC中使用AFnetworking请求数据然后刷新页面,由于网络请求是用block实现 ...

  6. 【解决】Node JS Error: ENOENT

    The Node Beginner Book 书中的实例代码当上传图片时会报Error: ENOENT, 原因:图片默认会选择系统的缓存文件夹下,在windows下无权访问C盘,所以就报错了.. 解决 ...

  7. node.js异步控制流程 回调,事件,promise和async/await

    写这个问题是因为最近看到一些初学者用回调用的不亦乐乎,最后代码左调来又调去很不直观. 首先上结论:推荐使用async/await或者co/yield,其次是promise,再次是事件,回调不要使用. ...

  8. Node.js 异步异闻录

    本文首发在个人博客:http://muyunyun.cn/posts/7b9fdc87/ 提到 Node.js, 我们脑海就会浮现异步.非阻塞.单线程等关键词,进一步我们还会想到 buffer.模块机 ...

  9. Node.js之异步编程

    > 文章原创于公众号:程序猿周先森.本平台不定时更新,喜欢我的文章,欢迎关注我的微信公众号. ![file](https://img2018.cnblogs.com/blog/830272/20 ...

随机推荐

  1. linux下查看动态链接库so文件的依赖的相关组建

    我们很多c程序在windows下是以dll形式展现的,在linux则是以so 形式展现的. windows一般不会因为编译dll文件的编译器版本不同而出先dll文件不能执行. 但是linux下,不同版 ...

  2. logistics回归理解

    多元回归方程:假设有一个因变量y和一组自变量x1, x2, x3, ... , xn,其中y为连续变量,我们可以拟合一个线性方程: y =β0 +β1*x1 +β2*x2 +β3*x3 +...+βn ...

  3. 分布式事务Hmily TCC源码--学习整合

    一.什么是分布式事务 分布式事务是指事务的参与者.支持事务的服务器.资源服务器以及事务管理器分别位于不同的分布式系统的不同节点上, 本质上来说,分布式事务是为了保证不同数据库的数据一致性 TCC事务主 ...

  4. asp.net asp.net application 升级到 asp.net web 解决找不到控件 批量生成.designer文件

    颇费周折后,其实很简单,只需要生成designer文件后,重新保存所有页面即可.就是懒得写.懒真的是一种病,手上不能懒,脑子里更不能懒,否则就是给自己挖坑,仔细认真,注意细节!!!! PS:注意修改p ...

  5. VBA 生成XML(转)

    需要引用连个库,Microsoft ADO Ext. 6.0 for DDL and Security, Miscrosoft  ActiveX Data Objects 2.7 Library . ...

  6. layui与echarts

    https://pan.baidu.com/s/1qM5ybqD-wAQNnWubdegBiA 在此感谢Layui给我这种不懂前端的人很大的帮助

  7. 分割list,将集合按规定个数分为n个部分。

    /** * 按指定大小,分隔集合,将集合按规定个数分为n个部分 * * @param list * @param len * @return */ public static <T> Li ...

  8. Go 学习

    学习Golang,可以在线实践:https://www.tutorialspoint.com/go/index.htm

  9. 探索未知种族之osg类生物---渲染遍历之器官协作

    好了,现在我们经过三节的介绍我们已经大体上明确了单线程模型(SingleThreaded)下 OSG 渲染遍历的工作流程.事实上无论是场景的筛选render还是绘制cull工作,最后都要归结到场景视图 ...

  10. vs2010单步调试崩溃

    vs2010在使用单步调试(F10,F11)功能时崩溃,如下图: 困扰了一段时间,度娘,google了很久也没有搜到有价值的解决方案,貌似问题非主流? 原因如下图(禁用即可): 当然这里NET Ref ...