看了就懂的Promise和回调函数


回调函数 (callback)

什么是回调函数?

被作为实参传入另一函数,并在该外部函数内被调用,用以来完成某些任务的函数,称为回调函数

也就是说回调函数是一个函数,作为 参数 传给另一个 JavaScript 函数,回调函数将会在这个函数执行时被调用执行。

示例

// 回调函数
function callback(param) {
    console.log('I am callback! param: ',param)
}
// 函数
function myFunc(param, callback) {
	setTimeout(()=>{
		callback(param) //执行回调函数
	},2000)
}

myFunc(1, callback) //等待2秒后:I am callback! param: 1

为什么要使用回调

示例
立即执行函数: 下面的两个函数都是立即执行的,能够正确的返回结果

function getInfo() {
    return 'I am Ryan'
}
function showInfo(param) {
    console.log(param)
}

showInfo(getInfo()) // I am Ryan

但是如果 getInfo 中需要访问网络请求,就不再能得到正确的结果了

function getInfo() {
	// 延时模拟网络请求
	setTimeout(()=>{
		return 'I am Ryan'
	},2000)
}
function showInfo(param) {
    console.log(param)
}

showInfo(getInfo()) // undefined

这时候回调函数就派上用场了:

function getInfo(callback) {
    setTimeout(() => {
      	let res = 'I am Ryan';
      	callback(res)
      	return res;
    }, 2000);
}
function showInfo(param) {
	console.log(param)
}

getInfo(showInfo) //等待2秒后:I am Ryan

Promise

Promise 是什么?

Promise 是一个对象,它代表了一个异步操作的最终结果 (完成或失败)。
本质上 Promise 是一个函数返回的对象,我们可以把回调函数绑定到它上面,这样就不需要在一开始就把回调函数作为参数传入这个函数了。

示例:回调函数与Promise

回调函数形式

//成功回调函数
function successCallback() {
    console.log('SUCCESS')
}
//失败回调函数
function failureCallback() {
	console.log('FAILURE')
}

function myFunc(param, success, failure) {
  	if (param) {
    	success()
  	} else {
    	failure()
  	}
}

myFunc(0, successCallback, failureCallback) // FAILURE

Promise形式

// successCallback、failureCallback 同上
function myFunc(param) {
	return new Promise((resolve, reject) => {
		if (param) {
        	resolve()
      	} else {
        	reject()
      	}
	})
}

myFunc(0).then(successCallback, failureCallback) //FAILURE

Promise 的三种状态

  • pending 初始状态,既不是成功,也不是失败
  • fulfilled 操作成功完成
  • rejected 操作失败

注:

  1. 处于 pending 状态的 Promise 对象可能会变为 fulfilled 状态并传递一个值给相应的状态处理方法,也可能变为失败状态(rejected)并传递失败信息。
  2. 当其中任一种情况出现时,Promise 对象的 then 方法绑定的处理方法(handlers)就会被调用,then 方法包含两个参数:onfulfilledonrejected,它们都是 Function 类型。
    • Promise 状态为 fulfilled 时,调用 thenonfulfilled 方法;
    • Promise 状态为 rejected 时,调用 thenonrejected 方法;

所以在异步操作的完成和绑定处理方法之间不存在竞争。

Promise 链式调用

连续执行两个或者多个异步操作是一个常见的需求,在上一个操作执行成功之后,再开始下一个的操作,并带着上一步操作所返回的结果。
在过去,要想做多重的异步操作,会导致经典的回调地狱:

// 模拟Http请求延时
function myRequest(type, callback) {
	setTimeout(() => {
      	let result = type + 1
      	callback(result)
      	return result
	}, 1000)
}
// 多重回调(仅作示例,实际情况 myRequest 可能是不同的函数)
myRequest(0, function (res) {
	myRequest(res, function (res) {
      	myRequest(res, function (res) {
        	console.log(res) //3
		})
	})
})

现在我们可以通过创造一个 Promise 链来实现这种需求:

function myRequest(type) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        let result = type + 1
        resolve(result)
      }, 1000)
    })
  }
  
// 链式调用(仅作示例,实际情况 myRequest 可能是不同的函数)
myRequest(0).then(res => {
	return myRequest(res)
}).then(res => {
    return myRequest(res)
}).then(res => {
    console.log(res) //3
})

// 或者
myRequest(0)
.then(res => myRequest(res))
.then(res => myRequest(res))
.then(res => {
    console.log(res) //3
})

注意: 一定要有返回值,否则,callback 将无法获取上一个 Promise 的结果。(如果使用箭头函数,() => x() => { return x; } 更简洁一些,但后一种保留 return 的写法才支持使用多个语句。)。

🌾 下一篇 帮你弄懂Promise原型方法then, catch, finally

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:撸撸猫 设计师:马嘣嘣 返回首页
评论

打赏作者

小天才程序员

人生得意须尽欢

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值