promise是什么?
1、主要用于异步计算
2、可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果
3、可以在对象之间传递和操作promise,帮助我们处理队列
异步操作的常见语法
- 事件监听
document.getElementById('#start').addEventListener('click', start, false);
function start() {
// 响应事件,进行相应的操作
}
// jquery on 监听
$('#start').on('click', start)
2.回调
// 比较常见的有ajax
$.ajax('http://www.wyunfei.com/', {
success (res) {
// 这里可以监听res返回的数据做回调逻辑的处理
}
})
// 或者在页面加载完毕后回调
$(function() {
// 页面结构加载完成,做回调逻辑处理
})
promise的基本用法
-
then中成功失败的执行
// resolve代表成功 reject失败 都是一个函数 let p = new Promise(function(reslove,reject){ //reslove('成功') //状态由等待变为成功,传的参数作为then函数中成功函数的实参 reject('失败') //状态由等待变为失败,传的参数作为then函数中失败函数的实参 }) //then中有2个参数,第一个参数是状态变为成功后应该执行的回调函数,第二个参数是状态变为失败后应该执行的回调函数。 p.then((data)=>{ console.log('成功'+data) },(err)=>{ console.log('失败'+err) })
Promise承诺:默认情况下是等待状态pending,如果有一天状态转变为成功就成功了,如果状态变成失败就失败了。状态一旦改变了就不能再改变了。
-
如果then中返回了一个promise 会将promise的结果继续传给第二then中(如果结果是将状态改成成功就走下一个then的成功回调,状态改为失败就走下一个then的失败回调)
function read( content ) { return new Promise(function( reslove,reject ) { setTimeout(function(){ if(content>4){ resolve(content) }else{ reject('小于4') } },1000) }) } read(1).then(( data )=>{ console.log(data) },( err )=>{ console.log(err) //小于4 return read(2) //将状态改为了失败 }) .then(( data )=>{ console.log('data',data) },( err )=>{ console.log(err) //小于4 })
-
第一个then不管是走成功还是失败的回到函数,只要返回一个普通值(不抛出错误或者返回promise),都会执行下一个then的成功的回调。
let p = new Promise(function(reslove,reject){ reject('失败1') }) p.then((data)=>{ console.log('成功'+data) },(err)=>{ console.log('失败'+err) //失败失败1 }) .then((data)=>{ console.log('成功1'+data) //成功1undefined },(err)=>{ console.log('失败1'+err) }) eg:抛出错误执行下一个then的失败 let p = new Promise(function(reslove,reject){ reject('失败1') }) p.then((data)=>{ console.log('成功'+data) },(err)=>{ console.log('失败'+err) //失败失败1 }) .then((data)=>{ console.log('成功1'+data) //成功1undefined throw Error('下一个失败') },(err)=>{ console.log('失败1'+err) }) .then((data)=>{ console.log('成功2'+data) },(err)=>{ console.log('失败2'+err) //失败2Error: 下一个失败 })
-
catch的用法
catch可以实现错误的捕获 一般写在最后,如果上面有自己的err会走自己的error。如果没有写就会走到catch
let p = new Promise(function(resolve,reject){ reject('失败') }); p.then((data)=>{ },(err)=>{ throw Error('错误') }) .then((data)=>{ },(err)=>{ console.log(err+'自己的err') //走自己的(输出:Error: 错误自己的err) throw Error('错误自己抛出的') }) .then((data)=>{ //没有自己的失败处理函数,走catch }).catch(e=>{ console.log(e+'公共的err') //输出:Error: 错误自己抛出的公共的err })
-
all的用法
Promise.all方法执行后返回的依旧是promise, all两个全成功才表示成功 。
function read(content) { return new Promise(function (resolve, reject) { setTimeout(function () { resolve(content) }, 1000) }) } let result = Promise.all([read(1), read(2)]); result.then((data) => { console.log(data) //[ 1, 2 ] })
有了all,就可以并行执行多个异步操作,并且在一个回调中处理所有的返回数据。返回的数据与传的参数数组的顺序是一样的。
-
race的用法
如果先成功了那就成功了, 如果先失败了那就失败了
function read(content) { return new Promise(function (resolve, reject) { setTimeout(function () { if(content>4){ resolve(content) }else{ reject(content) } }, 1000*content) }) } let result = Promise.all([read(5), read(2)]); result.then((data) => { console.log('成功'+data) },(err)=>{ console.log('失败'+err) //失败2 })
-
finally()用法
finally()
方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。该方法是 ES2018 引入标准的。promise .then(result => {···}) .catch(error => {···}) .finally(() => {···});
上面代码中,不管
promise
最后的状态,在执行完then
或catch
指定的回调函数以后,都会执行finally
方法指定的回调函数。下面是一个例子,服务器使用 Promise 处理请求,然后使用
finally
方法关掉服务器。server.listen(port) .then(function () { // ... }) .finally(server.stop);
finally
方法的回调函数不接受任何参数,这意味着没有办法知道,前面的 Promise 状态到底是fulfilled
还是rejected
。这表明,finally
方法里面的操作,应该是与状态无关的,不依赖于 Promise 的执行结果。finally
本质上是then
方法的特例。promise .finally(() => { // 语句 }); // 等同于 promise .then( result => { // 语句 return result; }, error => { // 语句 throw error; } );
上面代码中,如果不使用
finally
方法,同样的语句需要为成功和失败两种情况各写一次。有了finally
方法,则只需要写一次。它的实现也很简单。
Promise.prototype.finally = function (callback) { let P = this.constructor; return this.then( value => P.resolve(callback()).then(() => value), reason => P.resolve(callback()).then(() => { throw reason }) ); };
上面代码中,不管前面的 Promise 是
fulfilled
还是rejected
,都会执行回调函数callback
。从上面的实现还可以看到,
finally
方法总是会返回原来的值。// resolve 的值是 undefined Promise.resolve(2).then(() => {}, () => {}) // resolve 的值是 2 Promise.resolve(2).finally(() => {}) // reject 的值是 undefined Promise.reject(3).then(() => {}, () => {}) // reject 的值是 3 Promise.reject(3).finally(() => {})
-
reject()
Promise.reject(reason)
方法也会返回一个新的 Promise 实例,该实例的状态为rejected
。const p = Promise.reject('出错了'); // 等同于 const p = new Promise((resolve, reject) => reject('出错了')) p.then(null, function (s) { console.log(s) }); // 出错了
上面代码生成一个 Promise 对象的实例
p
,状态为rejected
,回调函数会立即执行。注意,
Promise.reject()
方法的参数,会原封不动地作为reject
的理由,变成后续方法的参数。这一点与Promise.resolve
方法不一致。const thenable = { then(resolve, reject) { reject('出错了'); } }; Promise.reject(thenable) .catch(e => { console.log(e === thenable) })
上面代码中,
Promise.reject
方法的参数是一个thenable
对象,执行以后,后面catch
方法的参数不是reject
抛出的“出错了”这个字符串,而是thenable
对象。 -
promise的静态方法
resolve: Promise.resolve([1,2,3]).then(function(data){ console.log(data); //[1,2,3] });
reject: Promise.reject([1,2,3]).then(null,function(err){ console.log('err',err) //err [ 1, 2, 3 ] });
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。