Promise,用于解决回调地域带来的问题,将异步操作以同步的操作编程表达出来,避免了层层嵌套的回调函数。
所谓的 promise,简单的来说就是一个容器,里面保存着某个未来才会结束的事件(也就是我们的异步操作)的结果。从语法上面来说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 api,各种异步操作都可以用同样的方法进行处理。
promise 对象代表一个异步操作,有三种状态:pending、fulfilled、reject
任何其他状态都无法改变这个状态。这也是 Promise 这个名字的由来。'承诺'表示其他手段无法改变它的状态。
promise其实就是一个异步编程方案,在 promise 出现之前总会遇到所谓的'回掉地域'的嵌套代码
step(1, function() {
step(2, function() {
step(3, function() {
……….
})
})
})
都知道这种"回调地狱",是一种很让人恼火的代码书写格式,嵌套多层之后会让人阅读起来怀疑人生的。但是这种"回调地狱"真的就只有格式的问题嘛?显然不是。
一个来自《YDKJS》的例子:一个程序员开发了一个付款的系统,它良好的运行了很长时间。突然有一天,一个客户在付款的时候信用卡被连续刷了五次。这名程序员在调查了以后发现,一个第三方的工具库因为某些原因把付款回调执行了五次。在与第三方团队沟通之后问题得到了解决。
上面的例子就是一个 信任问题 回调函数的方式会引发很多信任问题,例如重复调用,调用太晚等等问题。那么promise怎么解决上述两个问题的呢?
可读性 首先是 Promise 的 then 方法,支持我们在回调写在 then 方法中,让我们在日常开发中可以很清楚的看到,比如上面的代码就可以改写成
Promise.resolve(1).
.then(step => ++setp)
.then(step => ++setp)
.then(step => ++setp)
...
Promise 承诺的严谨性 它与普通的回调方式的区别在于
普通方式,回调成功之后的操作直接写在了回调函数里面,而这些操作的调用是由第三方控制
Promise方式 回调只负责成功之后的通知,而回调成功之后的操作放在 then 的回调函数里面,由 Promise 精确控制。
注意 Promise 的状态不可逆。一旦发生改变就没有办法改变成任何一种状态。Promise 只能是异步的,所以不会出现异步的同步调用。
无法取消 Promise 一旦新建它就会立即执行,无法中途取消
如果不设置回调函数,Promise 内部抛出的错误不会反应到外部。
当处于 pending 状态,无法得知目前进行到哪一阶段(刚开始还是快结束)
Promise 对象是一个构造函数,用来生成 Promise 实例
Promise 构造函数接收一个函数作为参数,该函数的两个参数分别是 resolve 和 reject,这两个参数也函数,由 JavaScript 提供,不需要自己添加
Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。但一般不建议给then加两个参数,建议使用.then完成resolved状态的操作,使用.catch完成rejected的操作。 像这样:
const promise = new Promise( (resolve,reject) => {
resolve('ok');
reject('error')
})
promise.then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
还可以用promise实现ajax的操作:
const getJSON = function(url){
const promise = new Promise((resolve,reject) => {
const handler = function(){
if(this.readyState !== 4){//这两个if语句主要用来判断请求是否成功
return;
};
if(this.status === 200){
resolve(this.response)//这是成功请求后,将返回的数据传到回调函数中
}else{
reject(new Error(this.statusText))//这是失败后,将原因返给catch
}
};
const xmlHttp = new XMLHttpRequest();//声明一个XMLHttpRequest对象的实例
xmlHttp.open("get", url);//设置要发送的方法和地址
xmlHttp.onreadystatechange = handler;//在这里调用上面定义的handler
xmlHttp.responseType = "json";
xmlHttp.setRequestHeader("Accept", "application/json");//设置请求头,规定接受json类型的数据
xmlHttp.send();//真正的发送请求
});
return promise;
};
getJSON("url").then( res => {
//成功后的操作
}).catch(err => {
//失败后的提示
})
Promise可以嵌套使用,就是将一个Promise实例作为另一个Promise实例的resolve方法的参数传入。
说说then方法,这个方法是定义在Promise的原型上的,then方法返回的是一个新的Promise实例,因此可以采用链式写法,即then方法后面调用另一个then方法。
再来说几个Promise常用的api吧!
Promise.prototype.finally():
Finally方法用于不管promise对象的最后状态如何,都会执行的操作
promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});
Promise.resolve():
这个方法用来将参数转变成Promise对象
参数是一个Promise实例:不改动
参数是一个thenable对象:会将这个对象转为 Promise 对象,然后就立即执行thenable对象的then方法。
参数不是具有then方法的对象,或根本就不是对象:返回一个新的Promise对象,状态为resolved
不带有任何参数:直接返回一个ersolved状态的Promise对象
Promise.reject() Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected
Promise.all():
const p = Promise.all([p1, p2, p3]);
用于将多个Promise实例,包装成一个新的Promise实例。这个方法接收一个数组作为参数,且都是Promise实例,如果不是,就会先调用Promise.resolve方法。 注意: 只有当数组中的实例的状态都是fulfilled,p才会变成fulfilled,此时,p1,p2,p3的返回值组成一个数组,传递给p的回调函数。 只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。
Promise.race(): 和all方法类似,也是讲多个Promise实例包装成一个。 但不一样的是,只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。
在实际开发中,我们总希望让同步函数同步执行,异步函数异步执行,但如果同步函数想用Promise来做处理,能否实现同步呢?答案是肯定的。 这就要说到**Promise.try()**方法了
const f = () => console.log('now');
Promise.try(f);
console.log('next');
// now// next
Promise 想必大家十分熟悉,想想就那么几个 api,可是你真的了解 Promise 吗?本文根据 Promise 的一些知识点总结了十道题,看看你能做对几道。
本文写给有一定Promise使用经验的人,如果你还没有使用过Promise,这篇文章可能不适合你,Promise标准中仅指定了Promise对象的then方法的行为,其它一切我们常见的方法/函数都并没有指定.
Async/Await替代Promise的6个理由:Async/Await是近年来JavaScript添加的最革命性的的特性之一。它会让你发现Promise的语法有多糟糕,而且提供了一个直观的替代方法。
Promise是JS异步编程中的重要概念,异步抽象处理对象,是目前比较流行Javascript异步编程解决方案之一,Promise 是一个构造函数, new Promise 返回一个 promise对象 接收一个excutor执行函数作为参数
这篇文章是考虑如何自己实现一个简单 Promise,用以理解 Promise。和原生 Promise的调用方法一样,支持链式调用,本文实现的方法只能用于参考Promise的原理,还有很多特性没有实现,比如 race,all 方法的实现。
在对数组进行一些遍历操作时,发现有些遍历方法对Promise的反馈并不是我们想要的结果。async/await为Promise的语法糖,文中会直接使用async/await替换Promise;map可以说是对Promise最友好的一个函数了,
最近在使用axios库时遇到了个问题,后端接口报了500错误,但前端并未捕获到。在axios整体配置的代码中,过滤http code时,调用了filter401()、filter500(),但是这里注意并未将两个filter函数的结果返回,也就是并未返回promise,这就是导致问题出现的原因
想必接触过Node的人都知道,Node是以异步(Async)回调著称的,其异步性提高了程序的执行效率,但同时也减少了程序的可读性。如果我们有几个异步操作,并且后一个操作需要前一个操作返回的数据才能执行
你可以在 .then 里面 return 一个 Promise,每次执行 .then 的时候都会自动创建一个新的 Promise,对调用者来说,Promise 的 resolved/rejected 状态是唯一的,Promise 构造函数不是解决方案,使用 Promise.resolve
Promise的一些用法在此不多赘述,本篇主要带领你手写一个Promise源码,学完你就会发现:Promise没有你想象中的那么难.本篇大概分为以下步骤:实现简单的同步Promise、增加异步功能、增加链式调用then、增加catch finally方法、增加all race 等方法、实现一个promise的延迟对象defer、最终测试
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!