1、回调函数:
原理:回调是一个函数被作为一个参数传递到另一个函数里,在那个函数执行完后再执行。( 也即:B函数被作为参数传递到A函数里,在A函数执行完后再执行B ),这样就可以控制代码执行顺序
// 引入fs
var fs = require('fs')
var myNumber = undefined;
//主体函数
function addOne(callback) {
fs.readFile('number.txt', function doneReading(err, fileContents) {
myNumber = parseInt(fileContents)
myNumber++
callback();
})
}
//功能函数
function logMyNumber() {
console.log(myNumber)
}
//启动
addOne(logMyNumber)
解析:当程序运行时,首先定义各个变量及函数。当addOne被调用时,它会启动一个readFile,由于读取文件是异步操作,它会将这个操作放进“任务队列”然后继续下一个准备执行的事情。如果没有什么要执行,节点将等待未完成的fs / network操作完成,否则它将停止运行并退出命令行
当读取完成文件(时间未定,取决于硬盘的速度),它才运行doneReading函数,并给它一个错误(如果有错误)和文件内容
最后调用callback回调函数输出mynumber,这样就能达到预想的结果。
2、promise:
(1)、普通的promise请求。
通过then方法返回回调函数-(回调函数看上面)。
var promiseTest = new Promise(function(resolve, reject){
console.log('直接执行')
setTimeout(function(){
resolve("[这是返回值]")
console.log('2秒后执行')
}, 1000)
})
promiseTest.then(function(res){
console.log('执行成功,返回值为',res)
},function(err){
console.log('执行失败,原因:',err)
})
(2)、支持链式调用,可以解决回调地狱问题
回调地狱:回调函数嵌套调用,外部回调函数异步执行的结果是嵌套的回调执行的条件。
// promise解决方式
function fn(str) {
var p = new Promise(function (resolve, reject) {
//处理异步任务
var flag = true;
setTimeout(function () {
if (flag) {
resolve(str)
}
else {
reject('操作失败')
}
})
})
return p;
}
fn('武林要以和为贵')
.then((data) => {
console.log(data);
return fn('要讲武德');//这个then里面返回的也是一个异步对象
})
.then((data) => {
console.log(data);
return fn('不要搞窝里斗')//返回异步对象
})
.then((data) => {
console.log(data);//没有异步对象
})
.catch((data) => {
console.log(data);
})
(3)all的用法
与then同级的另一个方法。
all方法提供了并行执行异步操作的能力,并在所有异步操作执行完后且执行结果都是成功的时候才执行回调。
function promiseClick1(){
let p = new Promise(function(resolve, reject){
setTimeout(function(){
var num = Math.ceil(Math.random()*20); //生成1-10的随机数
console.log('随机数生成的值:',num)
if(num<=10){
resolve(num);
}
else{
reject('数字太于10了即将执行失败回调');
}
}, 2000);
})
return p
}
function promiseClick2(){
let p = new Promise(function(resolve, reject){
setTimeout(function(){
var num = Math.ceil(Math.random()*20); //生成1-10的随机数
console.log('随机数生成的值:',num)
if(num<=10){
resolve(num);
}
else{
reject('数字太于10了即将执行失败回调');
}
}, 2000);
})
return p
}
function promiseClick3(){
let p = new Promise(function(resolve, reject){
setTimeout(function(){
var num = Math.ceil(Math.random()*20); //生成1-10的随机数
console.log('随机数生成的值:',num)
if(num<=10){
resolve(num);
}
else{
reject('数字太于10了即将执行失败回调');
}
}, 2000);
})
return p
}
Promise
.all([promiseClick3(), promiseClick2(), promiseClick1()])
.then(function(results){
console.log(results);//results是所有执行成功的结果集合
});
(4)、小结:then、race、catch、finally
then方法可以接受两个函数:第一个状态为成功的回调函数,第二个函数为失败的回调函数(可以不写,一般用catch方法捕获promise状态为失败的异常信息)、
race方法返回第一个执行成功的回调、
catch()获取异常信息、
finally始终会执行
ps:race方法谁先执行完成就先执行回调。先执行完的不管是进行了race的成功回调还是失败回调,其余的将不会再进入race的任何回调