最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 科技 - 知识百科 - 正文

ES6新特性:JavaScript中内置的延迟对象Promise代码详细介绍

来源:懂视网 责编:小采 时间:2020-11-27 20:24:20
文档

ES6新特性:JavaScript中内置的延迟对象Promise代码详细介绍

ES6新特性:JavaScript中内置的延迟对象Promise代码详细介绍:Promise的基本使用:利用Promise是解决JS异步执行时候回调函数嵌套回调函数的问题, 更简洁地控制函数执行流程;通过new实例化Promise, 构造函数需要两个参数, 第一个参数为函数执行成功以后执行的函数resolve, 第二个函数为函数执行失败以后执行的函数r
推荐度:
导读ES6新特性:JavaScript中内置的延迟对象Promise代码详细介绍:Promise的基本使用:利用Promise是解决JS异步执行时候回调函数嵌套回调函数的问题, 更简洁地控制函数执行流程;通过new实例化Promise, 构造函数需要两个参数, 第一个参数为函数执行成功以后执行的函数resolve, 第二个函数为函数执行失败以后执行的函数r

Promise的基本使用:

利用Promise是解决JS异步执行时候回调函数嵌套回调函数的问题, 更简洁地控制函数执行流程;

通过new实例化Promise, 构造函数需要两个参数, 第一个参数为函数执行成功以后执行的函数resolve, 第二个函数为函数执行失败以后执行的函数reject:

new Promise(function(resolve , reject) {
});

通过Promise,我们把回调函数用线性的方式写出来,而不是一层套一层, 这个函数有四层回调;

fn("args", function(a) {
 fn1("foo", function(b) {
 fn2("bar", function(c) {
 fn3("baz", function(d) {
 alert("回调成功,获知的内容为:"+a+b+c+d)
 })
 })
 })
})

以上的Demo只有包含成功的回调, 如果失败的回调也算的话, 也就更麻烦了;

如果使用Promise的方式,我们可以改装成线性的代码, 更加符合阅读的习惯,只要在then函数下写逻辑即可;

new Promise(function(resolve , reject) {
 resolve(1);
}).then(function(val) {
 console.log(val);
 return new Promise(function(resolve , reject) {
 resolve(2);
 });
}).then(function(val) {
 console.log(val);
 return new Promise(function(resolve , reject) {
 resolve(3);
 });
}).then(function(val) {
 console.log(val);
 return new Promise(function(resolve , reject) {
 resolve(4);
 });
}).then(function(val) {
 console.log(val);
});

这是一个ajax异步获取数据的例子, 我们使用了回调函数;

<html>
<head>
 <meta charset="utf-8">
</head>
<body>
<script>
 var callback = function(res) {
 console.log(res);
 };
 var ajax = function(url, callback) {
 var r = new XMLHttpRequest();
 r.open("GET", url, true);
 r.onreadystatechange = function () {
 if (r.readyState != 4 || r.status != 200) return;
 var data = JSON.parse(r.responseText);
 callback(data);
 };
 r.send();
 };
 //执行请求:
 ajax("http://www.filltext.com?rows=10&f={firstName}", callback);
 //再做别的事情;
</script>
</body>
</html>

因为ES6内置了Promise, 我们可以把以上的callback改写成promise的方式, 首先ajax函数返回一个Promise对象;

<html>
<head>
 <meta charset="utf-8">
</head>
<body>
 <script>
 var callback = function(res) {
 console.log(res);
 };
 var ajax = function(url) {
 return new Promise(function(resolve, reject) {
 var r = new XMLHttpRequest();
 r.open("GET", url, true);
 r.onreadystatechange = function () {
 if (r.readyState != 4 || r.status != 200) return;
 var data = JSON.parse(r.responseText);
 resolve(data);
 };
 r.send();
 })
 };
 //执行请求:
 ajax("http://www.filltext.com?rows=10&f={firstName}").then(function(data) {
 callback(data);
 });
 //再做别的事情;
 </script>
</body>
</html>

Promise实例的三种状态:

每一个实例化的Promise都有三个状态;pending(等待) rejected(拒绝) resolved(解决) ,默认的状态为pending,如果执行了resolve(), 那么这个promise的状态会变为resolve,如果执行了reject(), 那么这个promise的状态就会变成rejected, 而且这些状态是不可撤销的,一经更改,不会再变了;

then方法:

promise有一个then方法,then方法接收两个参数, 第一个为函数的成功回调, 第二个为函数的失败回调:

var promise = new Promise(function(resolve , reject) {
 resolve(); //执行成功回调;
});
console.log(0);
promise.then(function(val) {
 console.log(1); 
}, function() {
 console.log("失败");
});
console.log("2");
var promise = new Promise(function(resolve , reject) {
 reject();
});
console.log(0);
promise.then(function(val) {
 console.log(1);
}, function() {
 console.log("失败");
});
console.log("2");

then方法每一次都是返回不同的Promise实例,then的第一个参数是成功回调, 这个成功回调的参数为: 上一个Promise实例执行resolve方法的参数;

一般来说, then方法会返回当前的promise, 如果在then方法里面return 一个新的Promise实例,那么此时的then返回的就是新的Promise实例, 利用这个特性,就可以实现多层回调;

new Promise(function(resolve , reject) {
 resolve(1);
}).then(function(val) {
 console.log(val);
 return new Promise(function(resolve , reject) {
 resolve(2);
 });
}).then(function(val) {
 console.log(val);
 return new Promise(function(resolve , reject) {
 resolve(3);
 });
}).then(function(val) {
 console.log(val);
 return new Promise(function(resolve , reject) {
 resolve(4);
 });
}).then(function(val) {
 console.log(val);
});

不管代码是异步还是同步的, 都可以用Promise的then方法, 同步的代码直接写在then方法第一个参数, 把需要参数通过resolve传给下一个then方法,

如果是异步的代码, 就直接return一个Promise实例:

new Promise(function(resolve , reject) {
 resolve(1);
}).then(function(val) {
 console.log(val);
 return 2;
}).then(function(val) {
 console.log(val);
 return 3;
}).then(function(val) {
 console.log(val);
 return new Promise(function(resolve,reject) {
 //异步操作些这里
 resolve(4);
 });
}).then(function(val) {
 console.log(val);
 return 5;
}).then(function(val) {
 console.log(val);
});

catch方法:

catch方法和失败回调时一样的, 如果上一个异步函数抛出了错误了, 错误会被捕获, 并执行catch方法或者失败回调;

var promise = new Promise(function(resolve , reject) {
 resolve(); //执行成功回调;
});
console.log(0);
promise.then(function(val) {
 console.log("成功");
 throw new Error("heheda");
}).catch(function(e) {
 console.log(e);
}).then(function() {
 console.log("继续执行");
});

Promise中的错误是会一层层传递的, 如果错误没有没有被捕获, 会一直传递给下一个promise对象, 直到被捕获为止, 然后继续往下执行:

new Promise(function(resolve , reject) {
 resolve(1);
}).then(function(val) {
 console.log(val);
 return new Promise(function(resolve , reject) {
 throw new Error("err");
 });
 }).then(function(val) {
 console.log(val);
 return new Promise(function(resolve , reject) {
 resolve(3);
 });
 }).then(function(val) {
 console.log(val);
 return new Promise(function(resolve , reject) {
 resolve(4);
 });
 }).then(function(val) {
 console.log(val);
 }).catch(function(err) {
 console.log(err);
 }).then(function() {
 console.log("继续执行")
 })

构造函数Promise的四个方法:

构造函数Promise有四个方法, Promise.all, Promise.race, Promise.reject, Promise.resolve:

Promise.all(iterable)
返回一个promise对象,当iterable参数里所有的promise都被解决后,该promise也会被解决

要注意all方法是Promise函数的方法,不是实例的方法, 参数是一个数组, 数组里面全是Promise的实例 :

var p0 = new Promise(function(resolve) {
 setTimeout(function() {
 resolve(0)
 },1000);
})
var p1 = new Promise(function(resolve) {
 setTimeout(function() {
 resolve(1)
 },2000);
})
var p2 = new Promise(function(resolve) {
 setTimeout(function() {
 resolve(2)
 },3000);
})
Promise.all([p0,p1,p2]).then(function(arr) {
 console.log(arr)
})

Promise.race(iterable)

当iterable参数里的任意一个子promise被成功或失败后,父promise马上也会用子promise的成功返回值或失败详情作为参数调用父promise绑定的相应句柄,并返回该promise对象。

Promise.reject(reason)

调用Promise的rejected句柄,并返回这个Promise对象。

Promise.resolve(value)

用成功值value解决一个Promise对象。如果该value为可继续的(thenable,即带有then方法),返回的Promise对象会“跟随”这个value,采用这个value的最终状态;否则的话返回值会用这个value满足(fullfil)返回的Promise对象。

官方的例子:

<html>
<head>
 <meta charset="utf-8">
</head>
<body>
<p id="log"></p>
<script>
 'use strict';
 var promiseCount = 0;
 function testPromise() {
 var thisPromiseCount = ++promiseCount;

 var log = document.getElementById('log');
 log.insertAdjacentHTML('beforeend', thisPromiseCount + ') 开始(同步代码开始)<br/>');

 // 我们创建一个新的promise: 然后用'result'字符串解决这个promise (3秒后)
 var p1 = new Promise(function (resolve, reject) {
 // 解决函数带着解决(resolve)或拒绝(reject)promise的能力被执行
 log.insertAdjacentHTML('beforeend', thisPromiseCount + ') Promise开始(异步代码开始)<br/>');

 // 这只是个创建异步解决的示例
 window.setTimeout(function () {
 // 我们满足(fullfil)了这个promise!
 resolve(thisPromiseCount)
 }, Math.random() * 2000 + 1000);
 });

 // 定义当promise被满足时应做什么
 p1.then(function (val) {
 // 
输出一段信息和一个值 log.insertAdjacentHTML('beforeend', val + ') Promise被满足了(异步代码结束)<br/>'); }); log.insertAdjacentHTML('beforeend', thisPromiseCount + ') 建立了Promise(同步代码结束)<br/><br/>'); } testPromise(); </script> </body> </html>

既然有了Promise , 我们就可以把封装XMLHttpRequest封装成GET方法, 方便使用:

function get(url) {
 // Return a new promise.
 return new Promise(function(resolve, reject) {
 // Do the usual XHR stuff
 var req = new XMLHttpRequest();
 req.open('GET', url);

 req.onload = function() {
 // This is called even on 404 etc
 // so check the status
 if (req.status == 200) {
 // Resolve the promise with the response text
 resolve(req.response);
 }
 else {
 // Otherwise reject with the status text
 // which will hopefully be a meaningful error
 reject(Error(req.statusText));
 }
 };

 // Handle network errors
 req.onerror = function() {
 reject(Error("Network Error"));
 };

 // Make the request
 req.send();
 });
}

然后使用:

get('story.json').then(function(response) {
 console.log("Success!", response);
}, function(error) {
 console.error("Failed!", error);
});

假数据的地址可以自己设置, 可以通过控制台请求, 注意跨域的问题;

封装XMLHttpRequest成Promise异步加载图片的案例:http://www.gxlcms.com/

其他:

以上只是Promise的一些基础知识, 还有一些其他的知识点, 因为能力有限不一一介绍了(Promise.resolve的不同参数, 与Generator一起使用, Promise的附加方法, 等等等等);

把Promise的运行流程画出来, 对Promise的理解会好一点, Promise还是比较绕的

浏览器支持情况:

Chrome 32, Opera 1,Firefox 29, Safari 8 ,Microsoft Edge, 这些浏览器以上都默认支持;

文档

ES6新特性:JavaScript中内置的延迟对象Promise代码详细介绍

ES6新特性:JavaScript中内置的延迟对象Promise代码详细介绍:Promise的基本使用:利用Promise是解决JS异步执行时候回调函数嵌套回调函数的问题, 更简洁地控制函数执行流程;通过new实例化Promise, 构造函数需要两个参数, 第一个参数为函数执行成功以后执行的函数resolve, 第二个函数为函数执行失败以后执行的函数r
推荐度:
标签: 介绍 js 对象
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top