看了就懂的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形式

function myFunc(param) {
	return new Promise((resolve, reject) => {
		if (param) {
        	resolve()
      	} else {
        	reject()
      	}
	})
}

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

Promise的三种状态

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

【注】
处于 pending 状态的 Promise 对象可能会变为fulfilled 状态并传递一个值给相应的状态处理方法,也可能变为失败状态(rejected)并传递失败信息。
当其中任一种情况出现时,Promise 对象的 then 方法绑定的处理方法(handlers )就会被调用(then方法包含两个参数:onfulfilled 和 onrejected,它们都是 Function 类型。当Promise状态为fulfilled时,调用 then 的 onfulfilled 方法,当Promise状态为rejected时,调用 then 的 onrejected 方法, 所以在异步操作的完成和绑定处理方法之间不存在竞争)

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 的写法才支持使用多个语句。)。

©️2020 CSDN 皮肤主题: 黑客帝国 设计师:上身试试 返回首页