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>标签 ...
随机推荐
- TopCoder 14084 BearPermutations2【笛卡尔树+dp】
传送:https://vjudge.net/problem/TopCoder-14084 只是利用了笛卡尔树的性质,设f[i][j]为区间[i,j]的贡献,然后枚举中间最大的点k来转移,首先是两侧小区 ...
- [Xcode 实际操作]八、网络与多线程-(6)使用UIApplication对象打开地图
目录:[Swift]Xcode实际操作 本文将演示如何使用应用程序单例对象,打开地图的功能. 在项目导航区,打开视图控制器的代码文件[ViewController.swift] import UIKi ...
- C 语言实例 - 复数相加
C 语言实例 - 复数相加 C 语言实例 C 语言实例 使用结构体(struct)将两个复数相加. 我们把形如 a+bi(a,b均为实数)的数称为复数,其中 a 称为实部,b 称为虚部,i 称为虚数单 ...
- android intent安装apk
/** * 安装apk * * @param context * @param apkPath */ public static void installApk(Context context, St ...
- 调用webServer
1,右键引用 2
- [題解](最短路/二分)luogu_P1462通往奧格瑞瑪的道路
看到最大的最小值應該想到二分答案,這樣就解決了最小點權的問題,判血量就很好說,直接比較就行, 一個點是二分點權數組,複製一份然後排序,二分下標,速度較快 這麼簡單的題我竟然寫了這麼長時間 #inclu ...
- CVE-2017-5638——S2-045
一. 漏洞简介 Apache Struts是美国阿帕奇(Apache)软件基金会负责维护的一个开源项目,是一套用于创建企业级Java Web 应用的开源MVC框架,主要提供两个版本框架产品: Stru ...
- Azure service bus Topic基本用法
我们在升级一个POS系统的时候,决定使用微软公有云计算平台下的Azure ServiceBus 进行POS客户端与服务器的交互. 本文主要时作者在学习使用 Azure SDK for .NET 操作由 ...
- 转 测试linux中expect的timeout参数的作用
http://blog.csdn.net/msdnchina/article/details/50638818
- 547 Friend Circles 朋友圈
班上有 N 名学生.其中有些人是朋友,有些则不是.他们的友谊具有是传递性.如果已知 A 是 B 的朋友,B 是 C 的朋友,那么我们可以认为 A 也是 C 的朋友.所谓的朋友圈,是指所有朋友的集合.给 ...