本篇文章给大家带来了关于javascript的相关知识,其中主要整理了Promise的基本概念及使用方法的相关问题,包括了Promise基本概念、使用Promise解决回调地狱等等内容,下面一起来看一下,希望对大家有帮助。
本篇文章给大家带来了关于javascript的相关知识,其中主要整理了Promise的基本概念及使用方法的相关问题,包括了Promise基本概念、使用Promise解决回调地狱等等内容,下面一起来看一下,希望对大家有帮助。 【相关推荐:javascript视频教程、web前端】 一、前言异步是为了提高CPU的占用率,让其始终处于忙碌状态。 有些操作(最典型的就是I/O)本身不需要CPU参与,而且非常耗时,如果不使用异步就会形成阻塞状态,CPU空转,页面卡死。 在异步环境下发生I/O操作,CPU就把I/O工作扔一边(此时I/O由其他控制器接手,仍然在数据传输),然后处理下一个任务,等I/O操作完成后通知CPU(回调就是一种通知方式)回来干活。 《JavaScript异步与回调》想要表达的核心内容是,异步工作的具体结束时间是不确定的,为了准确的在异步工作完成后进行后继的处理,就需要向异步函数中传入一个回调,从而在完成工作后继续下面的任务。 虽然回调可以非常简单的实现异步,但是却会由于多重嵌套形成回调地狱。避免回调地狱就需要解嵌套,将嵌套编程改为线性编程。
二、Promise基本概念
let promise = new Promise(function(resolve,reject){ // 异步工作}) 通过以上语法,我们就可以把异步工作封装成一个
2.1 异步工作的封装文件模块的 以下代码封装了 代码如下: let promise = new Promise((resolve, reject) => { fs.readFile('1.txt', (err, data) => { console.log('读取1.txt') if (err) reject(err) resolve(data) })}) 如果我们执行这段代码,就会输出“读取1.txt”字样,证明在创建
2.2 Promise执行结果获取以上 then
promise.then(function(result),function(error))
举例: let promise = new Promise((resolve, reject) => { fs.readFile('1.txt', (err, data) => { console.log('读取1.txt') if (err) reject(err) resolve(data) })})promise.then( (data) => { console.log('成功执行,结果是' + data.toString()) }, (err) => { console.log('执行失败,错误是' + err.message) }) 如果文件读取成功执行,会调用第一个函数: PS E:\Code\Node\demos\03-callback> node .\index.js 读取1.txt 成功执行,结果是1 删掉 PS E:\Code\Node\demos\03-callback> node .\index.js 读取1.txt 执行失败,错误是ENOENT: no such file or directory, open 'E:\Code\Node\demos\03-callback\1.txt' 如果我们只关注成功执行的结果,可以只传入一个回调函数: promise.then((data)=>{ console.log('成功执行,结果是' + data.toString())}) 到这里我们就是实现了一次文件的异步读取操作。 catch如果我们只关注失败的结果,可以把第一个 亦或者采用更优雅的方式: let promise = new Promise((resolve, reject) => { fs.readFile('1.txt', (err, data) => { console.log('读取1.txt') if (err) reject(err) resolve(data) })})promise.catch((err)=>{ console.log(err.message)})
finally
例如: new Promise((resolve,reject)=>{ //something...}).finally(()=>{console.log('不论结果都要执行')}).then(result=>{...}, err=>{...})
三、使用Promise解决回调地狱3.1 回调地狱出现的场景现在,我们有一个需求:使用 由于 fs.readFile('1.txt', (err, data) => { console.log(data.toString()) //1 fs.readFile('2.txt', (err, data) => { console.log(data.toString()) fs.readFile('3.txt', (err, data) => { console.log(data.toString()) fs.readFile('4.txt', (err, data) => { console.log(data.toString()) fs.readFile('5.txt', (err, data) => { console.log(data.toString()) fs.readFile('6.txt', (err, data) => { console.log(data.toString()) fs.readFile('7.txt', (err, data) => { console.log(data.toString()) fs.readFile('8.txt', (err, data) => { console.log(data.toString()) fs.readFile('9.txt', (err, data) => { console.log(data.toString()) fs.readFile('10.txt', (err, data) => { console.log(data.toString()) // ==> 地狱之门 }) }) }) }) }) }) }) }) })}) 虽然以上代码能够完成任务,但是随着调用嵌套的增加,代码层次变得更深,维护难度也随之增加,尤其是我们使用的是可能包含了很多循环和条件语句的真实代码,而不是例子中简单的 3.2 不使用回调产生的后果如果我们不使用回调,直接把 //注意:这是错误的写法fs.readFile('1.txt', (err, data) => { console.log(data.toString())})fs.readFile('2.txt', (err, data) => { console.log(data.toString())})fs.readFile('3.txt', (err, data) => { console.log(data.toString())})fs.readFile('4.txt', (err, data) => { console.log(data.toString())})fs.readFile('5.txt', (err, data) => { console.log(data.toString())})fs.readFile('6.txt', (err, data) => { console.log(data.toString())})fs.readFile('7.txt', (err, data) => { console.log(data.toString())})fs.readFile('8.txt', (err, data) => { console.log(data.toString())})fs.readFile('9.txt', (err, data) => { console.log(data.toString())})fs.readFile('10.txt', (err, data) => { console.log(data.toString())}) 以下是我测试的结果(每次执行的结果都是不一样的): PS E:\Code\Node\demos\03-callback> node .\index.js12346957108 产生这种非顺序结果的原因是异步,并非多线程并行,异步在单线程里就可以实现。 之所以在这里使用这个错误的案例,是为了强调异步的概念,如果不理解为什么会产生这种结果,一定要回头补课了! 3.3 Promise解决方案使用
代码如下: let promise1 = new Promise((resolve, reject) => { fs.readFile('1.txt', (err, data) => { if (err) reject(err) resolve(data) })})let promise2 = promise1.then( data => { console.log(data.toString()) return new Promise((resolve, reject) => { fs.readFile('2.txt', (err, data) => { if (err) reject(err) resolve(data) }) }) })let promise3 = promise2.then( data => { console.log(data.toString()) return new Promise((resolve, reject) => { fs.readFile('3.txt', (err, data) => { if (err) reject(err) resolve(data) }) }) })let promise4 = promise3.then( data => { console.log(data.toString()) //..... })... ... 这样我们就把原本嵌套的回调地狱写成了线性模式。 但是代码还存在一个问题,虽然代码从管理上变的美丽了,但是大大增加了代码的长度。 3.4 链式编程以上代码过于冗长,我们可以通过两个步骤,降低代码量:
代码如下: function myReadFile(path) { return new Promise((resolve, reject) => { fs.readFile(path, (err, data) => { if (err) reject(err) console.log(data.toString()) resolve() }) })}myReadFile('1.txt') .then(data => { return myReadFile('2.txt') }) .then(data => { return myReadFile('3.txt') }) .then(data => { return myReadFile('4.txt') }) .then(data => { return myReadFile('5.txt') }) .then(data => { return myReadFile('6.txt') }) .then(data => { return myReadFile('7.txt') }) .then(data => { return myReadFile('8.txt') }) .then(data => { return myReadFile('9.txt') }) .then(data => { return myReadFile('10.txt') }) 由于 代码执行结果如下: PS E:\Code\Node\demos\03-callback> node .\index.js12345678910 这样就完成了异步且顺序的文件读取操作。
【相关推荐:javascript视频教程、web前端】 以上就是详细介绍JavaScript中Promise的基本概念及使用方法的详细内容,更多请关注模板之家(www.mb5.com.cn)其它相关文章! |