return;
}
resolve(content); //在异步行为成功时,调用resolve()方法
});
};
let promise = new Promise(executor);
解释一下上面的代码:
1: 创建Promise,包裹异步程序
Promise本身并不执行任何真正的异步程序。我们只是把异步程序包裹在一个Promise里面,这样做的目的其实是想把异步处理程序的结果给Promise,稍后再利用Promise提供的接口函数(then()
或者catch()
)来对结果进行处理。
2: 我们在Promise的executor函数里调用真正的异步操作函数。
我们在executor函数里调用fs.readFile( )函数。fs.readFile( )函数本身是一个异步行为,其方法的第三个参数为一个回调函数,用来接收文件读取的结果(失败时候的error和成功时候的content)。
3: 把异步程序的结果给Promise
我们在fs.readFile( )的回调函数里,在文件读取成功时调用resolve( )方法,失败的时候调用reject( )方法,把成功或者失败的结果通过2个函数的参数传入,为Promise在fulfilled或者rejected两种状态时提供数据。
四:编写Promise结果处理程序
前面我们已经了解到了怎么把一个异步处理事件包裹在一个Promise里面,并且通过resolve()和reject()把异步处理事件的结果传递的过程。终于来到了最后一步:使用结果数据(对比现实生活,你也可以理解为这一步叫做:验证承诺)。
Promise提供2个方法来处理结果: Promise.prototype.then()
和 Promise.prototype.catch()
。我们分别来看一下二者的功能:
1:Promise.prototype.then()
then()方法接收2个函数类行的参数:
1: 第一个参数为Promise在fulfilled状态(成功状态)时的回调方法
2: 第一个参数为Promise在rejected状态(失败状态)时的回调方法
我们以之前的读取文件为例子,看一下then()方法的使用:
这两个回调函数的参数也就是之前异步处理的结果数据。第一个函数的参数对应resolve()的参数content
,第二个回调函数对应reject()的参数error
。这样我们也就能在这2个回调函数里面拿到数据,从而根据你的业务需求编写对应的结果处理程序。
需要说明的是,这两个回调函数参数都不是必须的,并不强制要求你都要处理。下面的代码里,列觉了某2种结果处理程序,语法上都是合法的。只是正常的需求下,我们一般还是需要对成功和失败都要处理。
br
2: Promise.prototype.catch()
catch()方法只有一个参数:一个只处理rejected状态的回调函数。可能会有人疑问,then()已经可以同时处理2个状态,为什么还需要catch()方法?
原因在于前面我们提到的,在then()方法里,并不强制要求你提供处理rejected的回调函数。Promise有个特性:如果你没有添加rejected处理函数,那所有的失败会被自动忽略。
可能会有些开发者只关心成功状态,而忘了提供rejected处理函数,从而给整个程序埋下隐患,这样会造成很不好的用户体验。而catch()方法就是一个明确地处理rejected的方法,而不像在then()里面,因为是非必须参数而让人很容易忽略。
背景说了那么多,我们看看catch()怎么用:
promise.catch(function (error) {
console.log(error)
})
其实用法很简单,它其实等价于是有reject处理函数的then():
promise.then(null, function (error) {
console.log(error)
});
没有语法要求一个完整的Promise处理程序必须要有catch()方法。如果你没有使用catch()的习惯,最好总是不要忘记在使用then()的时候添加reject处理函数。
或者,如果你偶尔会忘记在then()里添加reject处理函数,那么记得使用catch()来为你做最安全的保障。
以上,就是关于Promise的基本概念和使用。在平常的开发中,Promise的使用还是非常频繁的,也很好用,所以我认为掌握Promise是一个必须的功课。
接下来,由浅入深 讲解 promise 实现原理
首先我们应该知道Promise是通过构造函数的方式来创建的(new Promise( executor )),并且为 executor函数 传递参数:
再来说一下Promise的三种状态: pending-等待, resolve-成功, reject-失败, 其中最开始为pending状态, 并且一旦成功或者失败, Promise的状态便不会再改变,所以根据这点:
其中$$status来记录Promise的状态,只有当promise的状态未pending时我们才会改变它的状态为’full’或者’fail’, 因为我们在两个status函数中使用了this,显然使用的是Promise的一些属性,所以我们要绑定resolve与reject中的this为当前创建的Promise;
这样我们最最最基础的Promise就完成了(只有头部没有四肢…)
浅的讲差不多了,深的来了 --> .then
接着,所有的Promise实例都可以用.then方法,其中.then的两个参数,成功的回调和失败的回调也就是我们所说的resolve和reject:
讲一下这里:
紧跟潮流
大前端和全栈是以后前端的一个趋势,懂后端的前端,懂各端的前端更加具有竞争力,以后可以往这个方向靠拢。
这边整理了一个对标“阿里 50W”年薪企业高级前端工程师成长路线,由于图片太大仅展示一小部分