为什么说promise不能取消是一个缺点
发布于 1 年前 作者 lzszone 5017 次浏览 来自 问答

什么场景下我需要取消一个promise? 我不理解的地方: http是无状态的,那取消是不是意味着新的请求? 还是说取消仅是本地取消,不处理之前请求的结果?

28 回复

取消promise并不只是针对网络请求啊,一串必须要顺序执行的Promise操作其中出现了需要跳出的地方不能取消还不是缺点吗

@scarletmu 抛出异常就取消了啊?我不知道场景,能大概假设一个场景吗

@lzszone 比如在注册时校验验证码,先查有没有对应用户,这是一个promise_get_user.然后在.then中再去查它对应的验证码promise_captche.最后返回.抛异常的时候就是user已经存在了,就通过抛异常的方式直接跳入catch,不再执行promise_captche了

就像你用try…catch执行到一半报错,代码能回滚吗?要回滚都是要自己写逻辑。

@Fov6363

是否有用户()
	.then(
		users.length > 0 throw new Error
		return 获得验证码
	)
	.then(验证码是否正确)
	.catch()

这样不是相当于就取消了吗?问题在哪儿我没明白

@lzszone 比如点赞之后又立刻取消点赞,正常来说必须等请求完成才能再取消的,如果 promise 可以取消就可以在请求发出前拦截下来了

@lzszone 我就是这个意思,对于promise来说,如果能取消的话,要比抛异常更优雅.

@scarletmu @Fov6363 @zy445566 @Binaryify 谢谢各位,最近在了解rxjs,对它提出的一些理念不是特别清楚,现在也还迷糊,我再看一段时间再交流

你不觉得jQuery的ajax.abort()方法很好用吗?

操作的取消和抛异常不一样吧。对于异步操作,请求发出去了就基本不能控制了,只能等待对方的结果。即使是abort,也不过是自己这边放弃,并不等于让对方自动进行回滚,因此对于幂等操作来说是无所谓的。但是非幂等操作 对数据进行修改,那只能自己回滚了。

@xltank 那具体到observerable对象里面的取消又是怎样的呢,我就是这里搞不明白,我觉得即使能取消也应该是单边取消啊,那有什么意义呢?promise不能取消也不是什么大问题呀。。需要一个场景来理解

@lzszone 为什么说promise不能取消是一个缺点??我个人认为是个伪命题吧

promise对象 实际返回的是 针对这个promise的状态合集 是操作个一组过程的集合

过程怎么能取消?就好像一个函数.

你执行了它就有返回值 中间过程是你的判断逻辑 你可以选择执行是否它 但是你函数执行的过程中你怎么取消啊???

如果你要需要按照执行过程调用使用promise的话 完全可以这样啊 其实没必要都提前写在.then里面

var P=Promise.resolve(1)

if(//true){ p2=P.then(data=>{console.log(data);return data+1}) }

if(P2){ P3=p2.then(data=>{console.log(data);return data+1}) }

if(P3){ P4=P3.then(data=>{console.log(data);return data+1}) }

你去设想这样一个爬虫场景,初始有1k多个待爬取的url,对每个url要执行的异步 : 1.请求页面, 2.网络失败重试 3.鉴权失败重新登录、切换账号等 4.通过其他接口切换一些Profile信息 5.解析页面数据、下载资源 6.数据库存储解析到的数据 7.数据库记录爬虫日志 8.翻页请求数据

要求顺序执行(因为要做爬取记录,防止重复数据等),任何一个环节报错都要捕捉并做处理(根据场景重试或者记录或者中断),你觉得不能随意try catch 的promise够用吗

其实这个需求已经有人提交了草案,但是被取消了: proposal-cancelable-promises,取消原因可以看一下这个 Issue:https://github.com/tc39/proposal-cancelable-promises/issues/70

感觉这就是一个伪命题,promise和能不能取消没有半毛线关系啊,取消或多或少带了一点业务相关吧,人家promise不是为了解决你这个东东的,,要取消你可以自己在封装一下。

比如说debounce,用户连续输入时,后一个最好能取消前一个(如网络请求,一触发就没有退路),这样比较干净,不然即浪费IO也浪费回调。 出于这种需求,于是有了 Observable.

这是不是缺点?不是!

这不是Promise结构应该做的事,不然叫Promise干嘛?:)

@PirateD311 我是做爬虫的,千万不要在爬虫项目里面依赖Promise,控制逻辑很难写

这个不能苛求Promise,Promise要解决的是异步逻辑的问题,是相对于callback的一大进步,但绝不是最佳方案

@yyrdl callback才是最方便的异步方案,与其引入新的特性,不如好好对callback进行合理组织,例如:http://caolan.github.io/async/

@wujohns 这个模块比较老旧了,性能还不如基于generator实现的zco ,可以尝试 这个 模块 https://github.com/suguru03/neo-async 对callback进行好的组织可以让代码结构好一点,如果可以像写同步代码一样平铺直叙的写逻辑岂不是更好

@yyrdl thanks,到时试下neo的那个,用callback的原因是因为平铺直叙的背后是对promise的强依赖

@wujohns 这个看模块的实现方式,co 早期就不依赖Promise,还有其他一些,实现比如suspend,genny 。还有我自己开发的 zco ,已经在项目里面大量使用了,亲可以尝试一下

@yyrdl 为什么会得出这个结论呢,我自己也做过比较大规模的node爬虫,爬虫也有很多异常处理、重试、切cookie、日志、断点继续、批量任务管理等等特性,不用基于promise的async根本控制不了异常和爬取顺序

promise要中途终止,需要手动抛出异常

哪有取消这个操作啊。取消就是伪命题。

@PirateD311 我之前做爬虫授权,授权流程分支异常的多,纯粹使用Promise的话不好写逻辑。比如某个地方判断成功接着做后面的事,失败则直接return 返回,Promise只能通过抛异常跳到最后,再return。 和co结合使用还行。个人观点Promise是不必要的。

@yyrdl 我们观点是一致的,复杂场景肯定Promise是不够用的,我的意思是Promise只是基础,现在大部分异步控制的解决方案,无论co、async、还是generator貌似都是基于Promise的,不能说项目里不依赖于Promise

@PirateD311 可以不依赖Promise

回到顶部