下面开始:

写在前面

假设现在一个日常开发会遇到这样一个需求:多个接口异步请求,第二个接口依赖于第一个

接口执行完毕之后才能利用数据进行一系列操作。一般会这样写:

            A.fetchData({url: 'http://......',success: function (data) {A.fetchData({// 要在第一个请求成功后才可以执行下一步url: 'http://......',success: function (data) {// ......}});}});

这样写没问题,但是有两个缺点:

1、当有多个操作的时候,会导致多个回调函数嵌套,不够美观

2、如果有几个操作没有前后顺序之分时,例如上面的后一个请求不依赖与前一个请求的返回结果的时候,

同样也需要等待上一个操作完成再实行下一个操作。

从ES6开始,Promise对象可以解决上述问题。

什么是Promise对象

一个Promise对象可以理解为一次将要执行的操作,使用了Promise对象之后可以用一种链式调用的方式

来组织代码,让代码更加直观。

resolve和reject

先看代码:

  function helloWorld (ready) {return new Promise(function (resolve, reject) {if (ready) {resolve("Hello World!");} else {reject("Good bye!");}});}helloWorld(true).then(function (message) {alert(message);}, function (error) {alert(error);});

上面的代码实现的功能非常简单,helloWord 函数接受一个参数,如果为 true 就打印 "Hello World!",

如果为 false 就打印错误的信息。helloWord 函数返回的是一个 Promise 对象。

在 Promise 对象当中有两个重要方法————resolve 和 reject。

resolve 方法可以使 Promise 对象的状态改变成成功,同时传递一个参数用于后续成功后的操作,

在这个例子当中就是 Hello World! 字符串。

reject 方法则是将 Promise 对象的状态改变为失败,同时将错误的信息传递到后续错误处理的操作。

then

Promise 对象有三种状态:
1.Fulfilled 可以理解为成功的状态
2.Rejected 可以理解为失败的状态
3.Pending 既不是 Fulfilld 也不是 Rejected 的状态,可以理解为 Promise 对象实例创建时候的初始状态。

helloWorld 的例子中的 then方法就是根据 Promise 对象的状态来确定执行的操作,resolve 时执行第一个

函数(onFulfilled),reject 时执行第二个函数(onRejected)。promise模式在任何时刻都处于以下三种状态之一:未完成(unfulfilled)、已完成(resolved)和拒绝(rejected)。以CommonJS Promise/A 标准为例,promise对象上的then方法负责添加针对已完成和拒绝状态下的处理函数。then方法会返回另一个promise对象,以便于形成promise管道,这种返回promise对象的方式能够支持开发人员把异步操作串联起来,如then(resolvedHandler, rejectedHandler); 。resolvedHandler 回调函数在promise对象进入完成状态时会触发,并传递结果;rejectedHandler函数会在拒绝状态下调用。

示例代码1:

function printHello (ready) {var promise = new Promise(function (resolve, reject) {if (ready) {resolve("Hello");} else {reject("Good bye");}});return promise;
}function printWorld () {console.log('World');
}function printExclamation () {console.log('!!!');
}printHello(true).then(function(message).then(printWorld).then(printExclamation).catch(function(error){console.log(error);});;

函数先执行printHello,返回一个promise对象,通过then将异步操作串联起来。
执行结果应该是 Hello
World
!!!

示例代码2:

  function helloWorld (ready) {return new Promise(function (resolve, reject) {if (ready) {resolve("Hello World!");} else {reject("Good bye!");}});}var _this = this;printHello(true).then(function (message) {var REQUEST_URL = 'https://raw.githubusercontent.com/facebook/react-native/master/docs/MoviesExample.json';return  fetch(REQUEST_URL).then((response) => response.json()).then((responseData) => {var movie = responseData.movies[1];console.log('data   =   ', movie.title);return movie.title;})},function (error) {return(error);}).then(function (message) {return message  + ' World';}).then(function (message) {return message + '!!!';}).then(function (message) {console.log(message);console.log('finally');}).catch(function(error){console.log(error);});

上面的代码中有两个promise,第一个promise执行完毕后也就是printHello之后,会执行下一个then,

这个then返回了一个获取数据的promise,后面的then拿到的promise都是指向这个promise对象的。上述例子通过链式调用的方式,按顺序打印出了相应的内容。then 可以使用链式调用的写法原因在于,每一次执行该方法时总是会返回一个 Promise 对象。另外,在 then onFulfilled 的函数当中的返回值,可以作为后续操作的参数。

catch

catch 方法是 then(onFulfilled, onRejected) 方法当中 onRejected 函数的一个简单的写法,也就是说

可以写成 then(fn).catch(fn),相当于 then(fn).then(null, fn)。使用 catch 的写法比一般的写法更加清晰明确。

新手使用容易犯的错误

1.忘记添加catch()方法

这是一个很常见的错误。很多程序员对他们代码中的promise调用十分自信,觉得代码永远不会抛出一个 error ,

也可能他们只是简单的忘了加 catch() 方法。不幸的是,不加 catch() 方法会让回调函数中抛出的异常被吞噬,

在你的控制台是看不到相应的错误的,这对调试来说是非常痛苦的。

为了避免这种糟糕的情况,我已经养成了在自己的promise调用链最后添加如下代码的习惯:

      somePromise().then(function () {return aPromise();}).then(function () {return anotherPromise();}).catch(function(error){console.log(error);});

即使你并不打算在代码中处理异常,在代码中添加 catch() 也是一个谨慎的编程风格的体现。在某种情况下

你原先的假设出错的时候,这会让你的调试工作轻松一些。

2.return的混淆乱用

在then方法内部,我们可以做三件事:
1.return 一个promise对象
2.return一个同步的值或者是 undefined
3.同步的 throw 一个错误

理解这三种情况之后,你就会理解promise了。

1.返回另一个promise对象

在有关promise的相关文章中,这种写法很常见,就像上文提到的构成promise链的一段代码:

        getUserByName('nolan').then(function (user) {return fetch(REQUEST_URL).then((response) => response.json()).then((responseData) => {}        }).then(function () {});

2.返回一个具体的值或者是 undefined

    getUserByName('nolan').then(fcuntion (user) {if (inMemoryCache[user.id]) {return inMemoryCache[user.id];  // returning a value!}return inMemoryCache[user.id];// returning a promise}).then(function (userAccount) {// I got a user account})

如果不调用return语句的话,javaScript里的函数会返回 undefined 。这也就意味着在你想返回一些值的时候,

不显式调用return会产生一些副作用。

出于上述原因,养成了一个个人习惯就是在then方法内部永远显式的调用return或者throw。我也推荐你这样做。

3.抛出一个错误

说到throw,这又体现了promise的功能强大。在用户退出的情况下,我们的代码中会采用抛出异常的方式进行处理:

    getUserByName('nolan').then(function (user) {if (user.isLoggedOut()) {throw new Error('user logged out!'); // throwing a error!}if (inMemoryCache[user.id]) {return inMemoryCache[user.id];      // returning a value!}return getUserAccountById(user.id);   // returning a promise!}).then(function (userAccount) {// I got a user account!}).catch(function (err) {// Boo, I got an error!});

如果用户已经登出的话, catch() 会收到一个错误,如果有promise对象的状态变为rejected的话,

它还会收到一个错误。

在使用promise的时候抛出异常在开发阶段很有用,它能帮助我们定位代码中的错误。比方说,

在then函数内部调用 JSON.parse() ,如果JSON对象不合法的话,可能会抛出异常,在回调函数中,这个异常会被吞噬,但是在使用promise之后,我们就可以捕获到这个异常了。

作者:梅庆
链接:http://www.jianshu.com/p/174d9892283f
來源:简书

浅谈Promise对象在ReactNative中的使用相关推荐

  1. java对象头_浅谈java对象结构 对象头 Markword

    概述 对象实例由对象头.实例数据组成,其中对象头包括markword和类型指针,如果是数组,还包括数组长度; | 类型 | 32位JVM | 64位JVM| | ------ ---- | ----- ...

  2. android 存储空间监控,浅谈 Android 内存监控(中)

    前言 在上篇 浅谈 Android 内存监控(上) 中,我们聊了 LeakCanary,微信的 Matirx 和美团的 Probe,它们各自有不同的应用场景,例如,在开发测试环境,我们会偏向用 Lea ...

  3. 美育在计算机教育中应用,浅谈在小学信息技术课堂中有效实施美育.

    <浅谈在小学信息技术课堂中有效实施美育.>由会员分享,可在线阅读,更多相关<浅谈在小学信息技术课堂中有效实施美育.(9页珍藏版)>请在人人文库网上搜索. 1.北京市第七届京美杯 ...

  4. 计算机在英语教学中的应用课题,浅谈信息技术在英语教学中的应用

    浅谈信息技术在英语教学中的应用 毕业论文 摘要:随着信息技术的发展, 计算机多媒体技术和网络被广泛地应用在外语教学中, 改变了传统外语教学模式.现代化外语教学提高了外语教学水平, 从而培养高素质的外语 ...

  5. 计算机在汽车专业中的应用,浅谈计算机技术在汽车行业中的应用.doc

    浅谈计算机技术在汽车行业中的应用 摘要:文章围绕计算机技术在汽车性能测试方面的运用.计算机技术在汽车监控方面的运用.计算机技术在汽车检修方面的运用三个方面展开讨论,对计算机技术在汽车行业中的运用模式进 ...

  6. 计算机技术在现代地球科学中的重要性,浅谈GIS技术在地球科学中的应用.doc

    浅谈GIS技术在地球科学中的应用.doc 浅谈GIS技术在地球科学中的应用 中图分类号:P9 文献标识码:A 文章编号:1007-0745(2014)02-0181-01 摘要:地理信息系统是指带各种 ...

  7. java对象头markword_浅谈java对象结构 对象头 Markword

    概述 对象实例由对象头.实例数据组成,其中对象头包括markword和类型指针,如果是数组,还包括数组长度; | 类型 | 32位JVM | 64位JVM| | ------ ---- | ----- ...

  8. java 对象之间转换_浅谈java对象之间相互转化的多种方式

    浅谈java对象之间相互转化的多种方式,对象,属性,参数,赋值,不支持 浅谈java对象之间相互转化的多种方式 易采站长站,站长之家为您整理了浅谈java对象之间相互转化的多种方式的相关内容. 第一种 ...

  9. [原创]浅谈持续集成在测试中的应用

    [原创]浅谈持续集成在测试中的应用 今天抽空理了下思路,来谈谈持续集成在测试中的应用,关于持续集成的介绍,可以参见我之前写的 浅谈我对持续集成的理解. 闲话少说,简单先介绍下,持续集成在测试中应用的范 ...

最新文章

  1. ADF Jar包循环引用会出问题
  2. python怎么安装包-Python-如何离线安装软件包?
  3. debain mariadb10配置root
  4. An error happened during template parsing (template: class path resource [templates/emp/list.html]
  5. 安卓APP_ 控件(8)—— AlertDialog
  6. httpurlconnection 封装_不要再封装各种Util工具类了,看看这个框架
  7. 美团推出极简版 为用户提供“米面粮油”等生活用品采购服务
  8. 浙江农林大学有计算机专业,浙江农林大学计算机科学与技术专业在职研究生
  9. 论文翻译:Real-Time High-Resolution Background Matting
  10. android音乐播放器flac,五款Android手机FLAC,APE无损音乐播放器
  11. python几行代码实现微信自动发消息
  12. [橘汁仙剑网出品]仙剑奇侠传六全剧情视频动画配音版[1080P][720P][H264]
  13. Using Oracle Database 11g Release 2 Result Cache in an Oracle RAC Environment
  14. 从“黑五”看亚马逊海外购的变与不变
  15. 微信小程序●云开发部署攻略
  16. 定时循环发送TCP消息(例如:控制设备的开关机等场景)—— 定时执行专家
  17. Android自定义控件系列二:自定义开关按钮(一)
  18. Mask2Former源码解析
  19. 写给计算机老师的一封信800,写给老师的一封信800字
  20. 【WCN685X】DFS认证5600~5650频宽CAC测试失败问题问题及解决方案

热门文章

  1. opencv 直线检测
  2. vs2019快捷键设置
  3. argparse subparsers()
  4. logging.Formatter 日期格式
  5. 机器学习算法之决策树
  6. Cannot find class for bean with name解决
  7. 九、distinct
  8. html将字符转成浮点数,stm32用串口接收到数据,怎么把接收到的字符串转换成浮点数?...
  9. 家用计算机内存最大是多少,电脑支持最大内存是多少?选用多大内存才合理?方法技巧要知道...
  10. java访问map_java.map使用