Promise中的next 另一个用法
const chainAsync = fns => {
let curr = 0 ; const next = (...args) => fns[curr++](next,...args); //执行fns[0](next) : next是一个闭包,包着fns 和 curr ,其中curr只有在next执行的时候才确定fns[curr++]中curr是多少,知识点(函数定义和执行)
//fns[1](next) : 执行的是fns[0]的next , next()执行时,curr为1
//fns[2](next) : 执行的时fns[1]的next , next()执行时,curr为2
next();//执行fns[0](next)
} //fns :的每个元素[fn1,fn2,fn3,...]
//每个元素接受的第一个参数是next,如fn1接受的第一个参数是next函数(...args) => fns[curr++](next,...args) 。由于这时候curr是1 在fn1内执行next就是执行fn2
//同理fn2接收的第一个参数也是next函数(...args) => fns[curr++](next,...args)。由于这时候curr是2 在fn2内执行next就是执行fn3
//后面同理,可见,每次执行next之后,curr才加一,到下一次再执行next的时候,curr是之前的值+1
//这就是闭包的魅力,不但可以缓存curr的值,还可以改变curr的值,到下次再执行时,curr是不同的值
//闭包中缓存的curr是指针?还是基本类型值?还是引用类型? curr是基本类型值,而缓存curr的是一个引用类型 {curr:0} 变量对象 //这里用了命令模式和闭包 : next是一个命令(宏),lambda,匿名函数,闭包
//命令模式就是一个匿名函数包着一个执行的函数 : 如 (fn)=>fn()
//闭包(函数)可以缓存一些变量(类似C++的静态变量,直到程序结束才销毁),这里闭包(函数)缓存的变量就如静态变量,只有这个闭包(函数)被销毁这些缓存的变量才被销毁 // chainAsync([next=>{
// console.log('开始');
// next('haha');//执行下一个函数fns[1](next,'haha')
// },(next,msg) =>{
// console.log(msg);
// next();//执行下一个函数fns[2]()
// },()=>console.log('end')]); //class实现
class ChainAsync{
constructor(fns){
this.fns = fns;
this.curr = 0;
this.next = this.next.bind(this);
// this.next = (...args) => this.fns[this.curr++](this.next,...args); //也可以
} next(...args){
this.fns[this.curr++](this.next,...args);
}
} // const fn1 = (next) => console.log('开始') || next('fn2请接收');//执行fn2(next,'fn2请接收') 这里next就是(next,'fn2请接收')=>fn2(next,'fn2请接收')
// const fn2 = (next,msg) =>console.log(msg); //输出'fn2请接收' // const chain = new ChainAsync([fn1,fn2]); // chain.next(); //输出:
//开始
//fn2请接收
Promise中的next 另一个用法的更多相关文章
- 原生JS中apply()方法的一个值得注意的用法
今天在学习vue.js的render时,遇到需要重复构造多个同类型对象的问题,在这里发现原生JS中apply()方法的一个特殊的用法: var ary = Array.apply(null, { &q ...
- 【JavaScript进阶】深入理解JavaScript中ES6的Promise的作用并实现一个自己的Promise
1.Promise的基本使用 // 需求分析: 封装一个方法用于读取文件路径,返回文件内容 const fs = require('fs'); const path = require('path') ...
- Promise对象的含义和基本用法
1.Promise的含义 Promise是异步编程的一种解决方案,比传统的解决方案(回调函数和事件)更合理更强大. 所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件 (通常是一 ...
- Nginx中root与alias的用法及区别:
Nginx中root与alias都是定义location {}块中虚拟目录访问的文件位置: 先看看两者在用法上的区别: location /img/ { alias /var/www/image/; ...
- Delphi中stringlist分割字符串的用法
Delphi中stringlist分割字符串的用法 TStrings是一个抽象类,在实际开发中,是除了基本类型外,应用得最多的. 常规的用法大家都知道,现在来讨论它的一些高级的用法. 1.CommaT ...
- C#中自己动手创建一个Web Server(非Socket实现)
目录 介绍 Web Server在Web架构系统中的作用 Web Server与Web网站程序的交互 HTTPListener与Socket两种方式的差异 附带Demo源码概述 Demo效果截图 总结 ...
- Linq中关键字的作用及用法
Linq中关键字的作用及用法 1.All:确定序列中的所有元素是否都满足条件.如果源序列中的每个元素都通过指定谓词中的测试,或者序列为空,则为 true:否则为 false. Demo: 此示例使用 ...
- 标准C++中的string类的用法总结
标准C++中的string类的用法总结 相信使用过MFC编程的朋友对CString这个类的印象应该非常深刻吧?的确,MFC中的CString类使用起来真的非常的方便好用.但是如果离开了MFC框架,还有 ...
- HTML中的target(_self,_blank)用法总结
HTML中的target(_self,_blank)用法总结 最近一个项目,多次遇到target='_self', target='_blank'的用法, 再次总结一下: 1.<a>标签 ...
随机推荐
- CSS优先级、CSS选择器、编写CSS时的注意事项
CSS的优先级: 内嵌样式>ID选择器>类选择器>标签选择器 内部样式>内部样式>外部样式 CSS的选择器: 选择器:在 CSS 中,选择器是一种模式,用于选择需要添加样 ...
- lombok常用注解
简介: Lombok能以简单的注解形式来简化java代码,提高开发人员的开发效率.例如开发中经常需要写的javabean,都需要花时间去添加相应的getter/setter,也许还要去写构造器.equ ...
- perl C/C++ 扩展(二)
第二讲perl 加载c/c++的库 先通过h2xs 创建一个新的工程 h2xs -A -n two_test 进入目录 cd two_test 创建一个mylib文件夹,存放静态库 mkdir myl ...
- kali 装好java后提示 -bash: /home/javainstall/jdk1.8.0_171/bin/java: 没有那个文件或目录
[问题现象] 在/etc/profile配置里面也是配置好了的,并且该目录是有java的 [问题原因] 出现这个问题的原因:64位的系统,安装了32位的Java. [解决方案] 通过网络搜索,发现通过 ...
- UVA11292(排序贪心)
笔者休息娱乐. ; int n, m, a; ll solve(int n, int m) { ll ans = ; priority_queue<int, vector<int>, ...
- python+selenium+requests爬取qq空间相册时遇到的问题及解决思路
最近研究了下用python爬取qq空间相册的问题,遇到的问题及解决思路如下: 1.qq空间相册的访问需要qq登录并且需是好友,requests模块模拟qq登录略显麻烦,所以采用selenium的dri ...
- 使用express+mongoDB搭建多人博客 学习(2)路由与模板
修改index.js路由规则: var express = require('express'); var router = express.Router(); /* GET home page. * ...
- appcloud 加载第三方页面loading效果
apiready = function() { var header = $api.byId('header'); $api.fixIos7Bar(header); var headerPos = $ ...
- [转]依赖注入框架Autofac的简单使用
本文转自:http://www.nopchina.net/post/autofac.html 话说nopcommerce底层用到了autofac框架,这里转了一篇文章简单说明一下: Autofac是一 ...
- C#中 添加 删除 查找Xml中子节点
//添加xml节点 private void AddXml(string image, string title) { XmlDocument xmlDoc = new X ...