1. Promise的状态
 
Promise对象有三个状态:
1. 进行中(pending)
2. 成功(resolved)
3. 失败(rejected)
 
2. 生成一个Promise对象
 
1. 构造函数
new Promise(function(resolve,reject){

});
resolve和reject函数是浏览器内部实现的,直接调用即可。
 
2. Promise.resolve
Promise.resolve()直接返回一个resolve状态的Promise对象
Promise.resolve可以用来生成一个then链
 
3. Promise.reject
Promise.reject()直接返回一个reject状态的Promise对象
 
3. Promise的then的用法
Promise的then永远返回一个新的Promise,Promise的catch是then(null,rejection)的语法糖,catch中也会返回一个新的Promise。
建议在Promise的then永远return或throw,不要只是执行一个函数。
例如:
var aPromise = new Promise(function (resolve) {
resolve(100);
});
var thenPromise = aPromise.then(function (value) {
console.log(value);
});
var catchPromise = thenPromise.catch(function (error) {
console.error(error);
});
console.log(aPromise !== thenPromise); // => true
console.log(thenPromise !== catchPromise);// => true
=== 是严格相等比较运算符,我们可以看出这三个对象都是互不相同的,这也就证明了 then 和 catch 都返回了和调用者不同的promise对象。
1. Promise的then内部可以做三种事情:
 
(1). return 另一个promise
(2). return 一个同步值(或者undefined)
因为javascript函数无返回值时候,默认返回undefined,所以只是执行一个函数,不return,默认就是返回undefined。
返回一个同步值在Promise中会将同步代码包裹为promise,得到的还是一个promsie。返回一个同步值是有用处的,例如,
一个异步值在内存中做了缓存,可以直接从内存中拿到该值,直接返回,不必再调用异步接口。
getUserByName('xxx').then(function(user){
if(imMemoryCache[user.id]){
return inMemoryCache[user.id];
}
return getUserAccountById(user.id);
}).then(function(userAccount){ });
(3). throw 一个同步异常
 
2. Promise的一些写法
new Promise(function(resolve,reject){
resolve(syncValue);
}).then(/*...*/) //可以写成
Promise.resolve(syncValue).then(/*...*/) //一个错误也可以写成
Promise.reject(new Error('...'))
这样无论成功或失败都可以后面的then和catch中捕获和继续操作
 
3. Promise的then中只能传递函数,如果为其他类型,例如另一Promise,会被解释为null,此时Promsie的值传递会穿透
 
例如:
Promise.resolve('foo').then(Promise.resolve('bar')).then(function(result){
console.log(result);
});
//会被解释为:
Promise.resolve('foo').then(null).then(function(result){
console.log(result);
});
第一个resolve的值会穿透到then,打印出foo。
 
4. then的四种写法的区别
// 写法一
f1().then(function () {
return f2();
}); // 写法二
f1().then(function () {
f2();
}); // 写法三
f1().then(f2()); // 写法四
f1().then(f2);
1. 写法1和4完全等价,f1值能传递到f2,f2的返回值也能继续向后面的then传递
2. 写法2相当于默认return undefined,无法向后面的then传递值
3. 写法3能够向后面传递f2的值,没有更深刻的解释(有懂的朋友请评论告知)
4. Promise的调用方法
每个then返回一个新的promise调用,这种写法被称为composing promises。
promise1.then(function(){
return promise2;
}).then(function(){
return promise3;
}).then(function(){
return promise4;
}).catch(function(err){
console.log(err);
});
5. Promise的并行执行
由于promise一旦被创建,就会立即执行,所以拿到一个Promise数组时候,其中的promise必然全部开始执行了。
因此要让一系列promise顺序执行,只能将promise放在一个函数中,在要执行的时候才去创建他,就是一个工厂
函数,promiseFactory。promise并行执行的代码应该如下:
function executeSequentially(promiseFactories){
var res = Promsie.resolve();
promiseFactories.forEach(function(promiseFactory){
res = res.then(promiseFactory);
});
return res;
}
//工厂函数只是简单的创建一个promise
function promiseFactory(){
return createAPromise();
}
6. Promise捕获错误
7. 实现一个Promise版本的ajax
//原生版本
function Http(){ } Http.prototype = {
get:function(opts){
return this.ajax(opts);
},
post:function(){
return this.ajax(opts);
},
ajax:function(opts){
return Promise(function(resolve,reject){
var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('...');
var {url,method,data,async,success,fail} = options;
var sendBody = null;
var qs = Object.keys(data).reduce(function(cur,pre,index){
return pre + '&' + encodeURIComponent(cur) + '=' + encodeURIComponent(data[cur]);
},'').slice(1);
if(medthod == 'get'){
url += '?' + qs;
}
else if(medhot == 'post'){
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
sendBody = qs || null;
}
xhr.onreadystatechange = function(){
if(xhr.readystate == 4){
if(xhr.status >= 200 && xhr.status < 300 || xhr.status == 304){
resolve(xhr,xhr.responseText);
}
}
else{
reject(xhr,xhr.responseText);
}
}
xhr.open(method,url,async);
xhr.send(sendBody);
});
}
} //jquery版本
function Http(){ } Http.prototype = {
get:function(opts){
return this.ajax(opts);
},
post:function(opts){
return this.ajax(opts);
},
ajax:function(){
return $.ajax(opts);
}
}
参考:https://juejin.im/entry/596f2ab2f265da6c25190f41
     http://javascript.ruanyifeng.com/advanced/promise.html#toc2
   https://www.kancloud.cn/kancloud/promises-book/44256

Promise用法总结的更多相关文章

  1. c/c++ 多线程 等待一次性事件 std::promise用法

    多线程 等待一次性事件 std::promise用法 背景:不是很明白,不知道为了解决什么业务场景,感觉std::async可以优雅的搞定一切的一次等待性事件,为什么还有个std::promise. ...

  2. ES6语法 promise用法

    ES6语法 promise用法 function doSomething(){ return new Promise((resolve,reject)=>{ resolve('jjjj');// ...

  3. es6的promise用法详解

    es6的promise用法详解 promise 原理 promise是es6的异步编程解决方案, 是es6封装好的对象: 一个promise有三种状态:Pending(进行中).Resolved(已完 ...

  4. [WinJS] Promise 用法

    初学 WinJS, 可能对 Promise 的用法不大清楚,本文简要说明一下 WinJS中 promise 的基本用法. 主要参考自:http://try.buildwinjs.com/#promis ...

  5. Es6 Promise 用法详解

     Promise是什么??    打印出来看看  console.dir(Promise) 这么一看就明白了,Promise是一个构造函数,自己身上有all.reject.resolve这几个眼熟的方 ...

  6. ES6 Promise 用法讲解

    Promise是一个构造函数,自己身上有all.reject.resolve这几个眼熟的方法,原型上有then.catch等同样很眼熟的方法. 那就new一个 var p = new Promise( ...

  7. Promise 用法

    Promise是一个构造函数,自己身上有all.reject.resolve这几个眼熟的方法,原型上有then.catch等同样很眼熟的方法. 那就new一个 Promise的构造函数接收一个参数,是 ...

  8. ES6 Promise用法讲解

    所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果. ES6 规定,Promise对象是一个构造函数,用来生成Promise实例. 下面代码创造了一个 ...

  9. ES6 Promise 用法转载

    Promise是一个构造函数,自己身上有all.reject.resolve这几个眼熟的方法,原型上有then.catch等同样很眼熟的方法. 那就new一个 var p = new Promise( ...

  10. promise用法详解

    es6的promise可谓是异步书写的一大福音,过去异步js书写是函数嵌套函数的方式,promise出现后书写异步js代码就变得美观得多了 以前的写法:回调函数不停嵌套 ajax('/banners' ...

随机推荐

  1. uvaoj 213 - Message Decoding(二进制,输入技巧)

    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  2. Qt-网络与通信-获取本机网络信息

    在网络应用中,经常需要获取本机主机名和IP地址和硬件地址等信息.运用QHostInfo.QNetworkInterface.QNetworkAddressEntry可以获得本机的网络信息. 上运行截图 ...

  3. 负数取余/整除,Python和C语言的不同

    总结一句:Python中负数整除,是向负无穷取整,所以导致负数取余不对 在数学公式中,两种语言的表示算法都是一样的,都是: r=a-n*[a/n] 以上,r是余数,a是被除数,n是除数. 唯一不同点, ...

  4. java 实现redis缓存

    由于项目加载时请求数据量过大,造成页面加载很慢.采用redis作缓存,使二次访问时页面,直接取redis缓存. 1.redis连接参数 2.连接redis,设置库 3.配置文件开启缓存 4.mappe ...

  5. 孤荷凌寒自学python第八十六天对selenium模块进行较详细的了解

    孤荷凌寒自学python第八十六天对selenium模块进行较详细的了解 (今天由于文中所阐述的原因没有进行屏幕录屏,见谅) 为了能够使用selenium模块进行真正的操作,今天主要大范围搜索资料进行 ...

  6. Linux内核设计笔记13——虚拟文件系统

    虚拟文件系统 内核在它的底层文件系统系统接口上建立一个抽象层,该抽象层使Linux可以支持各种文件系统,即便他们在功能和行为上存在很大差异. VFS抽象层定义了各个文件系统都支持的基本的.概念上的接口 ...

  7. mysql source 恢复 sql数据time_zone报错 已解决

    报了一些变量的错误,类似于"time_zone" 等错误 解决: [root@iz8vbilqy0q9v8tds55bqzz conf.d]# vi /etc/my.cnf [my ...

  8. CP文件覆盖问题

    # \cp -r -a aaa/* /bbb[这次是完美的,没有提示按Y.传递了目录属性.没有略过目录]

  9. TensorFlow安装解惑

    本文整理自网络,若有侵犯请告知. 1.安装环境 目前TensorFlow社区推荐的环境是Ubuntu, 但是TensorFlow同时支持Mac,Windows上的安装部署. 2.关于GPU版本 因为深 ...

  10. JavaScript初探系列之String的基本操作

    1.字符串转换 字符串转换是最基础的要求和工作,你可以将任何类型的数据都转换为字符串,你可以用下面三种方法的任何一种: var myStr = num.toString(); // "19& ...