Promise
Posted songya
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Promise相关的知识,希望对你有一定的参考价值。
为什么要有Promise?
Promise是异步编程的一种解决方案。有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。Promise对象提供了统一的接口,使得控制异步操作更加容易。
一、Promise的特点
1、对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
2、一旦状态改变,就不会再变,任何时候都可以得到这个结果。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。
二、基本用法
const promise = new Promise(function(resolve, reject){ // ... some code if(/*异步操作成功*/){ resolve(value); }else{ reject(error); } })
Promise的构造函数参数是一个函数,该函数的两个参数分别是resolve和reject,它们是两个函数,由javascript提供,不用自己部署。
resolve函数的作用:将Promise对象的状态由pending变为resolved,在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;reject函数的作用是,将Promise对象的状态由pending变为rejected,在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
promise.then(function(value){ //success }, function(error){ // 这个函数是可选的,不一定要提供 //failure })
使用Promise的栗子:Promise包装了一个图片加载的异步操作。如果加载成功,就调用resolve方法,否则就调用reject方法。
function loadImageAsync(url) { return new Promise(function(resolve, reject){ const image = new Image(); image.onload = function(){ resolve(image); }; image.onerror = function(){ reject(new Error(‘Could not load image at ‘+url) } image.src = url }) }
用Promise对象实现Ajax操作
const getJSON = function (url) { const promise = new Promise(function (resolve, reject) { const handler = function () { if (this.readyState !== 4) { return; } if (this.status === 200) { resolve(this.response) } else { reject(new Error(this.statusText)) } } const xhr = new XMLHttpRequest(); xhr.open(‘GET‘, url); xhr.onreadystatechange = handler; xhr.responseType = ‘json‘; xhr.setRequestHeader(‘Accept‘, ‘application/json‘); xhr.send(); }); return promise; } getJSON(‘/posts.json‘).then(function (json) { console.log(‘Contents:‘ + json) }, function (error) { console.log(‘出错了‘, error) })
getJSON内部,resolve函数和reject函数调用时,都带有参数。reject函数的参数通常是Error对象的实例,表示抛出的错误;resolve函数的参数除了正常的值以外,还可能是另一个Promise实例。
下图一、promise内部调用reject函数之后,在then方法内第二个参数函数里面输出抛出的错误。
下图二、(同上)虽然在最后有catch语句,但是不会被调用。
下图三、promise内部调用reject函数之后,没有then方法的第二个参数,那么会在catch方法里面输出抛出的错误。
var promise = new Promise(function(resolve, reject){ reject(new Error(‘123‘)) }).then(function(data){ console.log(data) },function(error){ console.log(1); console.log(error) }) //输出: 1 Error: 123
var promise = new Promise(function(resolve, reject){ reject(new Error(‘123‘)) }).then(function(data){ console.log(data) },function(error){ console.log(1); console.log(error) }).catch(function(err){ console.log(2); console.log(err) }) //输出: 1 Error: 123
var promise = new Promise(function(resolve, reject){ reject(new Error(‘123‘)) }).then(function(data){ console.log(data) }).catch(function(err){ console.log(2); console.log(err) }) //输出: 2 Error: 123
如果在then方法里面的第二次参数里面return new promise,那么会在catch里面捕获错误
var promise = new Promise(function(resolve, reject){ reject(new Error(‘123‘)) }).then(function(data){ console.log(data) },function(error){ console.log(1); return new Promise(function(resolve, reject){reject(new Error(‘abc‘))}) }).catch(function(err){ console.log(2); console.log(err) }) //输出: 1 2 Error: abc
catch方法并没有捕获到then方法内的new Error错误
var promise = new Promise(function(resolve, reject){ resolve(‘123‘) }).then(function(data){ console.log(data) console.log(new Error(‘error‘)); },function(error){ console.log(1); }).catch(function(err){ console.log(2); console.log(err) }) //输出 123 Error: error
并没有在catch方法里面输出error。
var promise = new Promise(function(resolve, reject){ resolve(‘123‘) }).then(function(data){ console.log(data) return new Promise((resolve, reject)=>{new Error(‘error‘)}); },function(error){ console.log(1); }).catch(function(err){ console.log(2); console.log(err) }) //输出 123
只有promise里面调用resolve、reject函数才会在then方法里面有输出
var promise = new Promise(function(resolve, reject){ resolve(‘123‘) }).then(function(data){ console.log(data) return new Promise((resolve, reject)=>{resolve(new Error(‘error‘))}); },function(error){ console.log(1); }).then(function(data){console.log(data)}) .catch(function(err){ console.log(2); console.log(err) }) //输出: 123 Error: error
var promise = new Promise(function(resolve, reject){ resolve(‘123‘) }).then(function(data){ console.log(data) return new Promise((resolve, reject)=>{reject(new Error(‘error‘))}); },function(error){ console.log(1); }).then(function(data){console.log(data)}) .catch(function(err){ console.log(2); console.log(err) }) //输出: 123 2 Error: error
Promise.race()
Promise.all()
async()/await()
yuansheng js
webassemble
以上是关于Promise的主要内容,如果未能解决你的问题,请参考以下文章
Typescript编译器无法从Promise resolve调用中推断类型