Javacript和AngularJS中的Promises

 

promise是Javascript异步编程很好的解决方案。对于一个异步方法,执行一个回调函数。

比如页面调用google地图的api时就使用到了promise。

 

function success(position){var cords = position.coords;console.log(coords.latitude + coords.longitude);
}function error(err){console.warn(err.code+err.message)
}navigator.geolocation.getCurrentPosition(success, error);

 

■ 如何处理多个异步方法

如果有很多异步方法需要按序执行呢?async1(success, failure), async2(success, failure), ...asyncN(success, failure),该如何处理呢?

最简单的,可能会这样写:

 

async1(function(){async2(function(){...asyncN(null, null);...}, null)
}, null)

 

以上的代码是比较难维护的。

我们可以让所有的异步方法执行完毕后出来一个通知。

 

var counter = N;
function success(){counter--;if(counter === 0){alert('done');}
}async1(success);
async2(success);
...
asyncN(success);

 

■ 什么是Promise和Deferred

deferred表示异步操作的结果,提供了一个显示操作结果和状态的接口,并提供了一个可以获取该操作结果相关的promise实例。deferred是可以改变操作状态的。

promise提供了一个用来和相关deferred交互的接口。

当创建一个deferred,相当于一个pending状态;
当执行resolve方法,相当于一个resolved状态。
当执行reject方法,相当于一个rejected状态。

我们可以在创建deferred之后,定义回调函数,而回调函数在得到resolved和rejected的状态提示后开始执行。异步方法不需要知道回调函数如何操作,只需要在得到resolved或rejected状态后通知回调函数开始执行。

■ 基本用法

→ 创建deferred

var myFirstDeferred = $q.defer();

这里,对于myFirstDeferred这个deferred,状态是pending,接下来,当异步方法执行成功,状态变成resolved,当异步方法执行失败,状态变成rejected。

→ Resolve或Reject这个dererred

假设有这样的一个异步方法:async(success, failure)

 

async(function(value){myFirstDeferred.resolve(value);
}, function(errorReason){myFirstDeferred.reject(errorReason);
})

 

在AngularJS中,$q的resolve和reject不依赖上下文,大致可以这样写:

async(myFirstDeferred.resolve, myFirstDeferred.reject);

→ 使用deferred中的promise

var myFirstPromise = myFirstDeferred.promise;myFirstPromise.then(function(data){}, function(error){})

 

deferred可以有多个promise.

 

var anotherDeferred = $q.defer();anotherDeferred.promise.then(function(data){},function(error){})//调用异步方法
async(anotherDeferred.resolve, anotherDeferred.reject);anotherDeferred.promise.then(function(data){}, function(error){})

 

以上,如果异步方法async成功执行,两个success方法都会被调用。

→ 通常把异步方法包裹到一个函数中

 

function getData(){var deferred = $q.defer();async(deferred.resolve,deferred.reject);return deferred.promise;
}//deferred的promise属性记录了达到resolved, reject状态所需要执行的success和error方法
var dataPromise = getData();
dataPromise.then(function(data){console.log('success');}, function(error){console.log('error');})

 

如果只关注success回调函数该如何写呢?

dataPromise.then(function(data){console.log('success');})

 

如果只关注error回调函数该如何写呢?

dataPromise.then(null, function(error){console.log('error');})或dataPromise.catch(function(error){console.log('error');
})

 

如果不管回调成功或失败都返回相同的结果呢?

var finalCallback = function(){console.log('不管回调成功或失败都返回这个结果');
}dataPromise.then(finalCallback, finalCallback);或dataPromise.finally(finalCallback);

■ 值链式

假设有一个异步方法,使用deferred.resolve返回一个值。

function async(value){var deferred = $q.defer();var result = value / 2;deferred.resolve(result);return deferred.promise;
}

 

既然返回的是promise,我们就可以不断then, then下去的。

var promise = async(8).then(function(x){return x+1;}).then(function(x){return x*2;})promise.then(function(x){console.log(x);
})  

以上,resolve出的值成为每一个链式的实参。

■ Promise链式

 

function async1(value){var deferred = $q.defer();var result = value * 2;deferred.resolve(result);return deferred.promise;
}function async2(value){var deferred = $q.defer();var result = value + 1;deferred.resolve(result);return deferred.promise;
}var promise = async1(10).then(function(x){return async2(x);})promise.then(function(x){console.log(x);
}) 

 

当然一种更易读的写法是:

function logValue(value){console.log(value);
}async1(10).then(async2).then(logValue);

 

async1方法的返回值成为then方法中的success方法中的实参。

如果从捕获异常的角度,还可以这样写:

async1().then(async2).then(async3).catch(handleReject).finally(freeResources);

 

■ $q.reject(reason)    

使用该方法能够让deferred呈现error状态,并给出一个出现error的理由。

var promise = async().then(function(value){if(true){return value;} else {return $q.reject('value is not satisfied');}
})

 

■ $q.when(value)

返回一个promise并带上值。

function getDataFromBackend(query){var data = searchInCache(query);if(data){return $q.when(data);} else {reutrn makeAasyncBackendCall(query);}
}

 

■ $q.all(promisesArr)

等待所有promise执行完成。

var allPromise = $q.all([async1(),async2(),...asyncN();
])allProise.then(function(values){var value1 = values[0],value2 = values[1],...valueN = values[N];console.log('all done');
})

 

转载于:https://www.cnblogs.com/darrenji/p/5184733.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/447934.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

男人沉默的真实原因

英国社会学家马克经过调查发现:男人每天的说话量,是女人的一半。但男人们也大多用于朋友圈中、工作中,而与爱人的聊天交流,每天可能不足15分钟,用词量不超过10%。 其实,男人有很多缄默的方法,每…

Visual Studio 使用说明文档、VScode 使用手册

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 我只是记录下地址,方便自已以后查看: Visual Studio 使用文档 内容如:

JAVA File的创建及相对路径绝对路径

JAVA File的创建及相对路径绝对路径 转载自 http://blog.sina.com.cn/s/blog_9386f17b0100w2vv.htmlFile f new File("D:/test/mytest.txt");//当执行这句话后在内存的栈空间存在一个f的应用,在堆空间里存在一个mytest.txt对象。注意 这个对象只含有文件…

肾有多好人就有多年轻 男女通用的补肾秘方

每天都坚持喝一碗,现在已经连续喝了三个多星期了,以前有好些白发的地方居然没有复发,而且现在一根也没有啊,我真的很开心。不仅白头发不见了,而且皮肤变白皙和光滑了好多,气色也比原来好了!好东西要大家分享…

Object.keys() Object.values()

Object.keys() //返回对象中各个键值对的键(key) Object.values() //返回对象中各个键值对的值(value) var obj { foo: "bar", baz: 42 };Object.keys(obj) // ["foo", "baz"]Object.values(obj) // ["ba…

vue 解决: *!!vue-style-loader!css-loader?{“sourceMap“:true}!../../../../vue-loader

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 问题描述 *!!vue-style-loader!css-loader?{“sourceMap”:true}!../../../../vue-loader/lib/style-compiler/index?{“vue”:true,…

计算机专业 程序员技术练级攻略(转载)

程序员技术练级攻略转载自: https://coolshell.cn/articles/4990.html 前言 你是否觉得自己从学校毕业的时候只做过小玩具一样的程序?走入职场后哪怕没有什么经验也可以把以下这些课外练习走一遍(朋友的抱怨:学校课程总是从理论出发&#xff…

35 岁之前不应该错过的 30 本书

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 PS:在这个书目中,我不偏好的书会直接放到最后,所以不是按原文顺序来。 1、《目送》 作者&#xff1a…

生活中意想不到的妙招

1、抹布变白 抹布是咱们家中最常见的东西,干家务绝对离不开它,擦桌椅板凳,擦灶台,油烟机,浴室,电器等等,家里总需要准备很多抹布,最难清理的恐怕就是厨房的抹布了吧?因为总是和油污…

“ 紫手环的力量 ” :我想,美好的生活应该是自已造就的...

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 我想或许我可以试试这个方法: 其实 我是真的打算试试,最近总是会忧虑,或许我应该自已努力给自已造就…

通过界面生成时不存在的数据刷新界面引起的卡顿问题

今天遇到了一个问题,就是有一个界面,在生成时之前请求数据,在界面中通过schedule 与unschedule不停查看本地是否收到此数据(通过发起request的Id),当收到之后刷新。 然后就引起了一个问题。界面弹出是有动画…

解决 VUE:[WDS] Errors while compiling. Reload prevented...- invalid expression: Unexpected token -- in

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 1. 在网上找了个组件,直接把代码放入自已的项目中报错,提示信息如黑框中: 2. 此组件原码就是这样用的…

长寿的十个秘诀 至少选择一个坚持实施

人人都想提高自己健康长寿的机率。下面的十个秘诀中,哪怕只选择一个,然后坚持实施,若干年后你会发现已经受益无穷。 1、喝茶 喝茶,特别是喝绿茶,其中的抗氧化剂可以抵挡有害物质对你身体的伤害。喝茶被证明可以减压…

vue中的slot插槽

1.无名插槽<body><div id"app">123</div><script src"https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><script type"text/javascript">//注册组件Vue.component("my-component",{templ…

linux 上 日志中查异常,指定显示异常前后日志内容

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 查异常cat -n abc.log |grep Exception|more如找到行数为&#xff1a;5201314行&#xff0c;再查看该行前后的异常信息cat -n abc.log |…

my40_MySQL锁概述之意向锁

本文在锁概述的基础上&#xff0c;通常实验举例&#xff0c;详细地介绍了意向锁的原理。 锁范围 全局锁&#xff08;global lock&#xff09;表锁&#xff08;table lock&#xff09;行锁 (row lock) ROW LOCK的粒度LOCK_REC_NOG_GAP, record lock with out gap lockLOCK_GAP&…

C语言的整型溢出问题

整型溢出有点老生常谈了&#xff0c;bla, bla, bla… 但似乎没有引起多少人的重视。整型溢出会有可能导致缓冲区溢出&#xff0c;缓冲区溢出会导致各种黑客攻击&#xff0c;比如最近OpenSSL的heartbleed事件&#xff0c;就是一个buffer overread的事件。在这里写下这篇文章&…

石牌村中的美好 ...

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 看了下我这些天的吃的&#xff0c;好像天天是盒饭 ... 不过 2 荤 2 素 11 元&#xff0c;大概是城中村才会这么便宜吧 。 村里有很多…

警惕 十种短命的生活方式

“忙忙忙&#xff0c;忙到白了头”。忙碌的白领阶层在“金钱”与“健康”的物物交换中&#xff0c;损失掉的是什么呢? 究竟是什么在日复一日地蚕食白领们的生命? 危险方式1&#xff1a;极度缺乏体育锻炼 在932名被调查者中&#xff0c;只有96人每周都固定时间锻炼&#xff…

Thymeleaf 简介、教程

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 Thymeleaf是一个适用于Web和独立环境的现代服务器端Java模板引擎。 Thymeleaf的主要目标是为您的开发工作流程带来优雅的自然模板 - 可…