js进阶五(js回调、promise、promise嵌套、异常处理、jquery使用promise)

js进阶五(js回调、promise、promise嵌套、异常处理、jquery使用promise)

丙申 2018-10-19 18:06:24  5366  收藏 5
展开
文章目录
同步读取
回调函数
回调机制处理异常
promise
promise嵌套
捕获异常
方法一
方法二
jquery中使用promise
同步读取
我们来看一个从文件读取内容的例子,以下是这个例子的目录结构


我们看下promiser.js的代码如下:

const fs = require("fs")
const path = require("path")

function getFileByPath(fPath){
    fs.readFile(fPath,'utf-8',(err,dataStr) => {
        if (err) throw err
        console.log("datastr",dataStr)

        return dataStr
    })
}

var ret = getFileByPath(path.join(__dirname,'./files/1.txt'))

console.log("ret",ret)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
结果我们看下log输出如下:

zhiliaodeMBP:promise zhiliao$ node ./promiser.js
ret undefined
datastr 1231
1
2
3
在JavaScript的世界中,所有代码都是单线程执行的,因为读取文件是耗时操作,所以执行到getFileByPath时,还没有读取完毕文件内容会输出undefined

回调函数
由于这个“缺陷”,导致JavaScript的所有网络操作,浏览器事件,都必须是异步执行。异步执行可以用回调函数实现:

const fs = require("fs")
const path = require("path")

function getFileByPath(fPath,callback){
    fs.readFile(fPath,'utf-8',(err,dataStr) => {
        if (err) throw err

        callback(dataStr)
    })
}

getFileByPath(path.join(__dirname,'./files/1.txt'),function(data){
    console.info(data)
})

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
我们看下结果

zhiliaodeMBP:promise zhiliao$ node ./promiser.js
1231
1
2
回调机制处理异常
上述例子代码不完善,如果读取文件内容失败,也就是出现异常,我们怎么处理?

const fs = require("fs")
const path = require("path")

function getFileByPath(fPath,callback,errCallBack){
    fs.readFile(fPath,'utf-8',(err,dataStr) => {
        if (err) return errCallBack(err)
        callback(dataStr)
    })
}

getFileByPath(path.join(__dirname,'./files/1.txt'),function(data){
    console.info(data)
},function(err){
    if(err) return console.info(err.message)
})


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
我们看下测试结果,我们看到是捕获了异常:

zhiliaodeMBP:promise zhiliao$ node ./promiser.js
ENOENT: no such file or directory, open '/Users/zhiliao/zhiliao/vue/promise/files/11.txt'
1
2
promise
以上是我们读取一个文件内容,如果我们连续读取多个文件内容呢?我们可以用一种循环嵌套的方式,但是嵌套的方法过于繁琐,我们可以利用es6中的新特性promise来实现

Promise 是一个 构造函数,既然是构造函数, 那么,我们就可以 new Promise() 得到一个 Promise 的实例;
在 Promise 上,有两个函数,分别叫做 resolve(成功之后的回调函数) 和 reject(失败之后的回调函数)
在 Promise 构造函数的 Prototype 属性上,有一个 .then() 方法,也就说,只要是 Promise 构造函数创建的实例,都可以访问到 .then() 方法
Promise 表示一个 异步操作;每当我们 new 一个 Promise 的实例,这个实例,就表示一个具体的异步操作;
既然 Promise 创建的实例,是一个异步操作,那么,这个 异步操作的结果,只能有两种状态:
5.1 状态1: 异步执行成功了,需要在内部调用 成功的回调函数 resolve 把结果返回给调用者;
5.2 状态2: 异步执行失败了,需要在内部调用 失败的回调函数 reject 把结果返回给调用者;
5.3 由于 Promise 的实例,是一个异步操作,所以,内部拿到 操作的结果后,无法使用 return 把操作的结果返回给调用者; 这时候,只能使用回调函数的形式,来把 成功 或 失败的结果,返回给调用者;
我们可以在 new 出来的 Promise 实例上,调用 .then() 方法,【预先】 为 这个 Promise 异步操作,指定 成功(resolve) 和 失败(reject) 回调函数;
const fs = require("fs")
const path = require("path")

function getFileByPath(fpath){
    var promise = new Promise(function(resolve,reject){

        fs.readFile(fpath,"utf-8",(err,dataStr)=>{
            if(err) return reject(err)
            resolve(dataStr)
        })
    })

    return promise
}

var promise = getFileByPath('./files/1.txt')

promise.then(function(data){
    console.log(data,"~~~")
},function(err){
    console.log(err.message,">>>>")
})

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
我们看下测试效果如下:

zhiliaodeMBP:promise zhiliao$ node ./promiser.js
1231 ~~~
1
2
我们简单梳理下这个promise例子的执行过程:
程序执行
1.首先加载getFileByPath进内存,
2.然后getFileByPath('./files/1.txt')调用该方法,执行getFileByPath方法内代码,执行readFile操作,这里是耗时操作
3.返回promise对象
4.promise.then传递回调函数
5.等待readFile执行完毕,执行回调函数

promise嵌套
我们还可以通过如下的方式实现批量读取文件内容
只需要在第一次读取完毕后,进行返回一个promise,然后在继续.then操作即可


function getFileByPath(fpath){
    var promise = new Promise(function(resolve,reject){

        fs.readFile(fpath,"utf-8",(err,dataStr)=>{
            if(err) return reject(err)
            resolve(dataStr)
        })
    })

    return promise
}

var promise1 = getFileByPath('./files/1.txt')


promise1.then(function(data){
    console.log(data,"~~~")
    var promise2 = getFileByPath('./files/2.txt')
    return promise2
},function(err){
    console.log(err.message,">>>>")
})
.then(function(data){
    console.log(data,"~~~")
},function(err){
    console.log(err.message,">>>>")
})

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
捕获异常
方法一
如果连续读取2个文件的内容,如果第一个文件读取失败,那么我们不应该停止程序,应该让他继续读取第二个文件,这就需要我们自己收到在第一次读取失败时候,做失败处理

const fs = require("fs")
const path = require("path")

function getFileByPath(fpath){
    var promise = new Promise(function(resolve,reject){

        fs.readFile(fpath,"utf-8",(err,dataStr)=>{
            if(err) return reject(err)
            resolve(dataStr)
        })
    })

    return promise
}

var promise1 = getFileByPath('./files/1但是.txt')


promise1.then(function(data){
    console.log(data,"~~成功~")
    return getFileByPath('./files/2.txt')
},function(err){
    console.log(err,"~~失败~")
    return getFileByPath('./files/2.txt')
})
.then(function(data){
    console.log(data,"~~~")
},function(err){
    console.log(err.message,">>>>")
})


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
测试结果如下:

zhiliaodeMBP:promise zhiliao$ node ./promiser.js{ [Error: ENOENT: no such file or directory, open './files/1但是.txt']
  errno: -2,  code: 'ENOENT',  syscall: 'open',
  path: './files/1但是.txt' } '~~失败~'wewr ~~~
1
2
3
方法二
只要有任何一个then语句出错,就终止全部语句
我们还可以利用catch语句块,不要在.then 里面去处理错误异常,而是需要在外面直接catch

const fs = require("fs")
const path = require("path")


function getFileByPath(fpath){
    var promise = new Promise(function(resolve,reject){

        fs.readFile(fpath,"utf-8",(err,dataStr)=>{
            if(err) return reject(err)
            resolve(dataStr)
        })
    })

    return promise
}

var promise1 = getFileByPath('./files/1.txt')


promise1.then(function(data){
    console.log(data,"~~成功~")
    return getFileByPath('./files/2等待.txt')
})
.then(function(data){
    console.log(data,"~~~")
})

.catch(function (err) { // catch 的作用: 如果前面有任何的 Promise 执行失败,则立即终止所有 promise 的执行,并 马上进入 catch 去处理 Promise中 抛出的异常;
    console.log('这处理方式:' + err.message)
  })
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
测试效果如下:

1231 ~~成功~
这是自己的处理方式:ENOENT: no such file or directory, open './files/2等待.txt'
zhiliaodeMBP:promise zhiliao$
1
2
3
jquery中使用promise

我们先来看一个原始的ajax请求
data.json

{
    "name":"safly",
    "age":30
}
1
2
3
4
<script src="./webpack_vue/node_modules/jquery/dist/jquery.min.js"></script>
1
<body>
<input type="button" value="getdata" id="btn">
<script>
$(function(){
  $("#btn").click(function(){
    $.ajax({
      url:"./data.json",
      type:"get",
      dataType:"json",
      success:function(data){
         console.log(data)
      }
    })
  })
})

</script>
</body>
</html>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值