自已实现的async 只实现了一步分功能

不得不说,人和人的技术确实有差距,同样的功能,其他人就是有办写写的更优雅性能更好

不论是C还是js

自已有功能但看着也比人家的丑好多。

//最终效果 同async
//目前实现了个人最常用的 serial 和 waterfall

//实现waterfall
//   async.waterfall([
//         function(callback){
//             callback(null, ‘one‘, ‘two‘);
//         },
//         function(arg1, arg2, callback){
//             callback(null, ‘three‘);
//         },
//         function(arg1, callback){
//             // arg1 now equals ‘three‘
//             callback(null, ‘done‘);
//         }
//     ], function (err, result) {
//        // result now equals ‘done‘
//     });

var async = (function () {
    //这个比较简单
    function whilst(fntest, fniterator, fnend) {
        if (fntest()) {
            fniterator(function (err) {
                if (err) {
                    fnend(err)
                }
                whilst(fntest, fniterator, fnend)
            })
        } else {
            fnend()
        }
    }
    //后一项作为前一项的最后一列参数 只用修改next指向
    function serial(tasks, endcallback) {
        function makeCallBack(index) {
            var hasnext = (index < tasks.length);
            if (hasnext) {
                var fn = function () {
                    var args = Array.prototype.slice(arguments)
                    var next = makeCallBack(index + 1)
                    args.push(next)
                    tasks[index].apply(null, args)
                }
                fn.hasNext = hasnext
                return fn
            } else return function () {
                endcallback()
            }
        }
        makeCallBack(0)()

    }
    function waterfall(tasks, endcallback) {
        function makeCallBack(index) {
            var hasnext = (index < tasks.length);
            if (hasnext) {
                var fn = function () {
                    //现在需要错误处理,如果第一项参数为err 则endcallback
                    //arguments 也要从第一项开始过滤
                    var args = Array.prototype.slice(arguments, 1)
                    if (arguments[0]) {
                        endcallback(arguments[0], null)
                        endcallback = null
                    } else {
                        var next
                        if (index + 1 == tasks.length) {
                            next = endcallback
                        } else {
                            next = makeCallBack(index + 1)
                            // args.push(next);
                        }
                        //这样只是把后一项函数,接在前一项之后。
                        //而前一项函数的其他参数,后一项并不能得到。
                        //把下一项调用的参数加到arg的前面
                        for (var key in arguments) {
                            if (key != "0") {
                                args.push(arguments[key]);
                            }
                        }
                        args.push(next);
                        tasks[index].apply(null, args)
                    }
                }
                return fn
            }
            //这样只是调用end方法,不能传参,要传参,需要向之前一样,把后一项接到tasks最后一项的callback上
            // else return function () {
            //     //返回 result
            //     endcallback(null)
            // }
        }
        //这样是直接调用返回的函数,下一个函数再调用下一个。
        //怎么把前一项的多余参赛传到下一项?
        makeCallBack(0)()
    }
    return {
        waterfall: waterfall,
        serial: serial,
        whilst: whilst
    }
})()

async.serial([
    function (callback) { console.log("1"); callback() },
    function (callback) { console.log("2"); callback() },
    function (callback) { console.log("3"); callback() }
], function () {
    console.log("end")
})

async.waterfall([
    function (callback) { console.log("1"); callback(null, "a"); },
    function (arg1, callback) { console.log("arg1" + arg1); console.log("2"); callback(null, "err3", "d"); },
    function (arg1, arg2, callback) { console.log("3"); callback(null, "res"); }
], function (err, result) {
    console.log("end");
    console.log(result);
})

var count = 0;

async.whilst(
    function () { return count < 10; },
    function (callback) {
        count++;
        console.log(count)
        setTimeout(callback, 100);
    },
    function (err) {
        // 5 seconds have passed
    }
    );

//迭代器
// (function () {
//     function getiter(tasks) {
//         var i;
//         for (i = 0; i < tasks.length; i++) {
//             (function (index) {
//                 var hasnext = ((index + 1) < tasks.length);
//                 tasks[index].hasNext = hasnext;
//                 console.log(index + " " + tasks[index].hasNext)
//                 if (tasks[index].hasNext) {
//                     tasks[index].next = tasks[index + 1]
//                 }
//             })(i)
//         }
//         return tasks[0]
//     }
//     var tasks = [
//         function () { console.log("1") },
//         function () { console.log("2") },
//         function () { console.log("3") },
//         function () { console.log("4") },
//     ]
//     var task = getiter(tasks)
//     while (task.hasNext) {
//         task();
//         task = task.next;
//     }

// })()
时间: 2024-08-13 01:44:13

自已实现的async 只实现了一步分功能的相关文章

如何在CAD中绘制长方体?只需简单四步

如何在CAD中绘制长方体?只需简单四步.在日常的工作中,特别是一些CAD行业,日常的基本工作就是编辑绘制CAD图纸,在绘制CAD图纸的时候需要借助一下工具来进行绘制,比如说CAD编辑器来绘制CAD图纸既方便又快捷,但是在绘制图纸的时候也会遇到许多的文件,那就是如何在CAD中绘制长方体?有什么好的办法吗?具体要怎么来进行操作?下面我们就来一起看看具体操作步骤吧. 使用步骤一:首先电脑中没有下载安装CAD编辑器的小伙伴们,还是需要在日常使用的电脑中任意的打开一个浏览器,在浏览器的搜索框中搜索迅捷CA

用Python实现一个端口扫描,只需简单几步就好

一.常见端口扫描的原理 0.秘密扫描 秘密扫描是一种不被审计工具所检测的扫描技术. 它通常用于在通过普通的防火墙或路由器的筛选(filtering)时隐藏自己. 秘密扫描能躲避IDS.防火墙.包过滤器和日志审计,从而获取目标端口的开放或关闭的信息.由于没有包含TCP 3次握手协议的任何部分,所以无法被记录下来,比半连接扫描更为隐蔽. 但是这种扫描的缺点是扫描结果的不可靠性会增加,而且扫描主机也需要自己构造IP包.现有的秘密扫描有TCP FIN扫描.TCP ACK扫描.NULL扫描.XMAS扫描和

你只差这两步 | 将Sentinel 控制台应用于生产环境

摘要: 这是围绕 Sentinel 的使用场景.技术对比和实现.开发者实践等维度推出的系列文章的第四篇. 第一篇回顾:Dubbo 的流量防卫兵 | Sentinel如何通过限流实现服务的高可用性 - 传送门 第二篇回顾:RocketMQ 的保险丝| Sentinel 如何通过匀速请求和冷启动来保障服务的稳定性 - 传送门 第三篇回顾:技术选型:Sentinel vs Hystrix - 传送门 Sentinel 是阿里中间件团队研发的面向分布式服务架构的轻量级高可用流量控制组件,于今年7月正式开

快速体验 Sentinel 集群限流功能,只需简单几步

? Pic by Alibaba Tech on Facebook 集群限流 可以限制某个资源调用在集群内的总 QPS,并且可以解决单机流量不均导致总的流控效果不佳的问题,是保障服务稳定性的利器. Sentinel 从 1.4.0 版本开始提供集群流控特性,但使用 Sentinel 集群限流需要对一系列的动态数据源进行相关配置,并且需要对开源控制台进行一些改造,有一定的使用成本.为了大家更好地理解集群流控并快速地使用,我们提供了云上版本的 Sentinel 集群限流控制台示例.只需要简单的几步即

应对IBM V7000磁盘故障,你只差这一步!

一.IBM V7000简要: 第一个IBM自主研发的中端存储2.0产品,架构上突破传统,吸收了DS和IBM横向扩展架构XIV的精华. 第一次集"EasyTier自动分层""虚拟化""精简调配"三大存储效率于一身的磁盘阵列,使IBM Storwize V7000当之无愧的成为更加看重存储效率的中端存储市场上的杀手级产品. 第一次把DS8000的RAID技术和自动分层.SVC虚拟化架构以及XIV的赏心悦目的管理界面等高端存储上的技术用在中端存储上,拥

对于 MVVM 我想说:自已的事情自已做,控制器就简化了!

太阳火神的美丽人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转载请保留此句:太阳火神的美丽人生 -  本博客专注于 敏捷开发及移动和物联设备研究:iOS.Android.Html5.Arduino.pcDuino,否则,出自本博客的文章拒绝转载或再转载,谢谢合作. 先来几个彩蛋: http://numbbbbb.gitbooks.io/-the-swift-programming-language-/ htt

Async in C# 5.0(C#中的异步编程Async) 蜗牛翻译之第一章

p { display: block; margin: 3px 0 0 0; } --> 写在前面 在学异步,有位园友推荐了<async in C#5.0>,没找到中文版,恰巧也想提高下英文,用我拙劣的英文翻译一些重要的部分,纯属娱乐,简单分享,保持学习,谨记谦虚. 如果你觉得这件事儿没意义翻译的又差,尽情的踩吧.如果你觉得值得鼓励,感谢留下你的赞,祝各位爱技术的园友在今后每一次应该猛烈突破的时候,不选择知难而退.在每一次应该独立思考的时候,不选择随波逐流,应该全力以赴的时候,不选择尽力

[转载]18只狐狸吃葡萄

挺有意思的文章. 有时候故事能给予人意想不到的启发.最近听到一个18只狐狸吃葡萄的寓言,透过不同狐狸面对葡萄诱惑产生的心理反应与行为,让我不经反思现实生活中自已是哪一只狐狸呢? 故事讲的是在一位农夫的果园里,紫红色的葡萄挂满了枝头,令人垂涎三尺.当然,这种厚味也逃不过在果园外安营扎寨的狐狸们,它们早就想享受一下了. 第一只狐狸发现葡萄架远远高出它的身高.它站在下面想了想,不愿意就次放弃.想了一会儿,它发现葡萄架旁边的梯子,回想农夫曾经用过它.它也学着农夫的样子爬上去,顺利地摘到了葡萄. (它直接

python学习笔记 async and await

用asyncio提供的@asyncio.coroutine可以把一个generator标记为coroutine类型,然后在coroutine内部用yield from调用另一个coroutine实现异步操作. 为了简化并更好地标识异步IO,从Python 3.5开始引入了新的语法async和await,可以让coroutine的代码更简洁易读. 请注意,async和await是针对coroutine的新语法,要使用新的语法,只需要做两步简单的替换: 把@asyncio.coroutine替换为a