回调函数与Promise

1. 回调函数

1.1 回调函数的目的

获取函数中异步操作的结果,则必须通过回调函数获取

1.2 回调函数本质

回调函数的本质就是拿一个函数当参数传递给异步方法.在这个异步函数的内部调用传进来的函数,并把所需要传递出去的数据作为这个函数的参数,这样数据就传递出去.

1.2.1 示例
function fn(callback){
	setTimeout(()=>{
		let data = '数据'
		callback(data)
	},1000)
}
fn((data)=>{
	console.log(data);
})

说明:
该示例中fn函数体里面有一个异步操作(setTimeout),要想获得这个异步操作的结果,就传递一个函数作为fn函数的参数传递进去,fn函数用形参callback来接收该函数.在异步操作的内部,通过调用该callback(参数),其中callback的参数就是需要传递出去的数据.然后调用fn函数时候,其参数里面写一个函数,并在该函数的参数接收数据.
传递进入的函数就叫做回调函数

1.3 回调使用

场景:由于读取文件速度不一样,导致异步任务中读取出来的数据不能保证顺序.为了保证顺序,所以就在回调里面套用回调,这样便形成了回调地狱
比如:

let fs = require('fs')
//输出内容通过回调来保证顺序
fs.readFile('./data/a.txt', (err, data) => {
    if (err) return console.log('读取失败')
    console.log(data.toString())
    fs.readFile('./data/b.txt', (err, data) => {
        if (err) return console.log('读取失败')
        console.log(data.toString())
        fs.readFile('./data/c.txt', (err, data) => {
            if (err) return console.log('读取失败')
            console.log(data.toString())
        })
    })
})

为了解决回调地狱,所以引入Promise

2. Promise

  1. Promise说明:Promise是一个容器,Promise是立即执行的,但是往往里面放异步任务.
  2. Promise有两个状态:resolve(成功) reject(失败).通过resolve(data)和reject(err)向外抛出结果
2.1 示例
	let fs = require('fs')

	let p = new Promise((resolve,reject)=>{
		//一个异步任务
		fs.readFile('./data/a.txt',(err,data)=>{
			if(err){
				reject(err)//把容器的状态变为失败,返回err
			}else{
				resolve(data)//把容器状态改为成功,返回data
			}
		})
	})
	//使用
	p.then((data)=>{
		console.log(data.toString())
	},(err)=>{
		console.log('读取文件失败了'+err)
	})
//then方法的第一个参数 对应的是 resolve(data)
//		  第二个参数 对应的是 reject(err)

2.2 实际使用
let fs = require('fs')
let p1 = new Promise((resolve, reject) => {
    fs.readFile('./data/a.txt', (err, data) => {
        if (err) reject(err)
        else resolve(data)
    })
})
let p2 = new Promise((resolve, reject) => {
    fs.readFile('./data/b.txt', (err, data) => {
        if (err) reject(err)
        else resolve(data)
    })
})
let p3 = new Promise((resolve, reject) => {
    fs.readFile('./data/c.txt', (err, data) => {
        if (err) reject(err)
        else resolve(data)
    })
})
p1.then((data) => {
    console.log(data.toString())
    return p2
}, (err) => {
    console.log('读取文件失败了' + err)
})
    .then((data) => {
        console.log(data.toString())
        return p3
    }, (err) => {
        console.log('读取文件失败了' + err)
    })
    .then((data) => {
        console.log(data.toString())
    }, (err) => {
        console.log('读取文件失败了' + err)
    })

通过then方法里成功调向外抛出Promise实例来实现链式调用

2.3 封装一下
let fs = require('fs')

let filePath1 = './data/a.txt'
let filePath2 = './data/b.txt'
let filePath3 = './data/c.txt'

function readFile(filePath) {
    return new Promise((resolve, reject) => {
        fs.readFile(filePath, (err, data) => {
            if (err) reject(err)
            else resolve(data)
        })
    })
}
//使用
readFile(filePath1).then(data => {
    console.log(data.toString())
    return readFile(filePath2)
}, err => {
    console.log('读取文件失败' + err)
})
    .then(data => {
        console.log(data.toString())
        return readFile(filePath3)
    }, err => {
        console.log('读取文件失败' + err)
    })
    .then(data => {
        console.log(data.toString())
    }, err => {
        console.log('读取文件失败' + err)
    })	
2.4 链式调用

还有一种场景,需要对数据进行链式处理

new Promise((resolve,reject)=>{
	setTimeout(()=>{
		resolve('数据')
	},1000)
}).then(data=>{
	//继续处理
	//return Promise.resolve(data+'111')
	return data+'111'
}).thenn(data=>{
	//继续处理
	//return Promise.resolve(data+'222')
	return data+'222'
})thenn(data=>{
	//处理
})
2.5 all方法

场景:当需要两个异步请求同时获得时,才能进行下一个操作

Promise.all([
    new Promise((resolve,reject)=>{
      $ajax({
        url:'',
        success:(data)=>{
          console.log('结果1'+data)
        }
      })
    }),
  new Promise((resolve,reject)=>{
    $ajax({
      url:'',
      success:(data)=>{
        console.log('结果2'+data)
      }
    })
  })
]).then((data)=>{
  //data是一个数据,一次保存上面Promise里抛出的值
  console.log(data[0])
  console.log(data[1])
})
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值