[关闭]
@frank-shaw 2019-07-03T14:17:59.000000Z 字数 3247 阅读 2472

《JavaScript with promises》简要笔记

javaScript


概述

要了解promise,需要先了解JavaScript中的异步机制,详细可查阅笔记《<深入理解node.js>中的异步机制相关部分》,连接为:https://www.zybuluo.com/frank-shaw/note/488651

代码对比

首先来看一下,不使用promise的情况,我们是如何通过回调函数callback来实现我们想要的异步功能的:
屏幕快照 2016-09-02 19.27.17.png-170.6kB

使用promise来实现异步功能的话,最标准的代码是这样的:
屏幕快照 2016-09-03 14.00.40.png-230.9kB

摘录

Fortunately there are only two cases. The resolver function passed to the Promise constructor executes synchronously. And all callbacks passed to then and catch are invoked asynchronously.

这段主要讲述的是Promise中也可以分同步和异步的,resolver函数构造器上的内容就是同步的,而回调函数(then catch)上的内容就是异步的。

Rejections and errors propagate through promise chains.

这句话表达的是,rejections与error是会随着Promise链进行传递的,一直传递下去。

Async functions and promises are contagious. After you start using them they natu‐ rally spread through your code.As a general rule, any function that uses a promise should also return a promise. 

一旦一个函数使用了promise之后,那么与之相关联的所有函数都建议使用promise。

this style of code creates multiple execution paths that can be difficult to reason about and create inconsistent behavior.

不要在一个函数中使用包含有promise内容的条件判断,如果该函数有可能返回promise也有可能不返回promise,那么这就是非常不合理的一种设置。

额外

另外,还了解到的是,在promise链中,作用域也是分层次的,也有内层作用域与外层作用域之分。如果需要传递作用域或者某一个函数到下一层Promise中,那么需要借助比较特殊的技术来实现,详细可以查看bind() call() 与apply()等函数。而BlueBird则提供了封装好的函数bind()来让我们来调用,如果使用该函数调用bind(this),那么调用bind(this)的这一层promise里的参数我们可以传递到任意一层去,这是优点。如果想要在某一层停止呢,那么可以在该层调用bind(null)来停止这样的调用。很棒!

BlueBird相关

BlueBird包装node.js中的promise

使用的函数是promisify():Bluebird provides a convenient function named promisify that wraps node-style functions with ones that return a promise。

BlueBird的return()方法与tap()方法

这两个函数适用的一种情况是这样的:当我们想要在多层Promise中使用同一个变量的时候,我们怎么做。

第五章--错误handler

Any error that occurs in a function that returns a promise should be used to reject the promise instead of being thrown back to the caller.

这句话表述的是:如果在一个需要返回promise的函数中出现了错误,那么该函数应该拒绝发送promise,而不是将错误返回给caller。

all the code you write inside promise callbacks is wrapped in an implicit try block.

所有你写入到promise 回调函数里的内容都被看成是try/catch模块中的try部分。你只需要在接下来的调用中使用catch方法就可以了。

The catch function returns a new promise similar to then, but the promise that catch returns is only rejected if the callback throws an error. In other words, you must explicitly rethrow an error inside a catch callback if you want the rejection to continue propagating through the promise chain. 

实际上呢,catch模块也会返回一个promise的,通常情况下返回的只是reject因为只有在发生err的时候才会调用到catch模块。与try/catch相似,如果当前catch模块不想要处理这个err,那么完全可以再抛出去,让err给promise链中的下一环处理。

Remember that a promise invokes each callback in a separate turn of the event loop. At the beginning of each turn the stack is empty, so none of the functions called in previous turns appear in the stack when the error occurs.

在调试的时候,需要记住的是:promise都是由异步机制产生,所以从stack中来查找代码err的话,不容易通过上下层关系找到,这个时候就需要额外的调试方法了(chrome中有如何应对的调试机制)。

个人非常喜欢下面这段代码(实例演示了race方法与setTimeout的用法):

  1. function getData(){
  2. var timeAllowed = 500;
  3. var deadline = Date.now() + timeAllowed;
  4. var freshData = ajax(/*someURL*/);
  5. var cachedData = fetchFromCache().then(function (data){
  6. return new Promise( function (resolve){
  7. var timeRemaining = Math.max(deadline - Date.now(), 0);
  8. setTimeout(function(){
  9. resolve(data);
  10. },timeRemaining);
  11. });
  12. });
  13. var failure = new Promise(function (resolve, reject){
  14. setTimeout(function(){
  15. reject(new Error('unable to fetch data in allotted time'));
  16. },timeAllowed);
  17. });
  18. return Promise.race([freshData,cachedData,failure]);
  19. }
  20. getData().then(function (data){
  21. console.log('received data;');
  22. console.log(data);
  23. }).catch(function(err){
  24. console.log('Unable to get data;');
  25. console.log(err);
  26. });

个人感受

1.需要了解 函数编程、JavaScript中的异步I/O机制才可以更好了解promise的部分。
2.确实有很多需要注意的点,在编程中需要学习。
3.外国人写书好懂一些。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注