专业的编程技术博客社区

网站首页 > 博客文章 正文

ES6 Promise对象(es6对象操作)

baijin 2024-10-27 19:21:43 博客文章 10 ℃ 0 评论

ES6 规定, Promise对象是一个构造函数, 下面代码生成了一个Promise实例。

const promise = new Promise(function(resolve, reject){
resolve(100) //调用成功的回调函数
// reject(500) //调用失败的回调函数
})
//console.log(promise);

promise

.then(() => console.log("成功,表示得到我们想要的结果,可以继续往下执行"))
.then(() => console.log("成功可以无限调用then方法"))
.catch(() => console.log("失败了,也表示得到结果,但是结果并非我们所愿"))


Promise构造函数接受一个函数作为参数, 该函数的两个参数分别是resolve和reject。它们是两个函数, 由 JavaScript 引擎提供, 不用自己部署。

resolve 表示成功执行的回调函数

reject 表示失败执行的回调函数

pending 表示等待中, 或者进行中, 还没有得到结果

Promise使用场景

下面用实际案例进行演示, 封装一个读文件duwenjian()函数, 这个函数接收url作为路径参数:

在浏览器环境中, 用Ajax按顺序读取三个文件, 为了解决回调黑洞问题, 使用Promise对象:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Document</title>
</head>
<body>
<button>请求数据</button>
</body>
<script type="text/javascript" src="data/jquery-3.3.1.min.js"></script>
<script type="text/javascript">
// const promise = new Promise(function(resolve, reject){
// resolve()
// //reject()
// })
// console.log(promise)
function duwenjian(url){
    return new Promise(function(resolve, reject){
    $.ajax({
    url: url,
    success: function(data){
    resolve(data)
    // console.log(data)
    },
    error: function(err){
    reject(err)
    // console.log(err)
    }
    })
    })
}
$('button').click(function(){
    duwenjian("data/1.json").then((data)=>{
    console.log('1成功了', data)
    return duwenjian("data/2.json")
    }).then((data)=>{
    console.log('2成功了', data)
    return duwenjian("data/3.json")
    }).then((data)=>{
    console.log('3成功了',data)
    })
});
</script>
</html>

在Nodejs环境中读文件

var fs = require('fs');
function duwenjian(url){
return new Promise(function(resolve, reject){
fs.readFile(url, "utf8", (err, data)=>{
if(err){
reject(err); //失败执行
return;
}
resolve(data); //成功执行
})
})
}
duwenjian("./data/1.txt").then((data)=>{
console.log(data)
return duwenjian("./data/2.txt")
})
.then((data)=>{
console.log(data)
return duwenjian("./data/3.txt")
})
.then((data)=>{
console.log(data)
})
.catch((err)=>{
console.log()
})

回调黑洞问题解决了, 将原来的"嵌套模式"变为"队列模式"。

Promise实例生成以后, 可以用then方法分别指定resolved状态和rejected状态的回调函数。

then方法可以接受两个回调函数作为参数。

第一个回调函数是Promise对象的状态变为resolved时调用。

第二个回调函数是Promise对象的状态变为rejected时调用。

其中, 第二个函数是可选的, 不一定要提供, 可以使用catch()方法替代。这两个函数都接受Promise对象传出的值作为参数。

promise.then((data)=>{
console.log(data);
},(err)=>{
console.log(err)
})

等价于以下写法:

promise.then((data)=>{
console.log(data);
})
.catch((err)=>{
console.log(err)
})

Promise的实例拥有then()和catch()方法用来处理成功和失败的事情, 这两方法是定义在原型对象中的。

异步语句的成功, 要将数据通过resolve(数据)传出去, 这个数据将成为then函数的参数。

异步语句的失败, 要将错误信息通过reject(err)传出去, 这个数据将成catch函数的参数。

Promise一定是某个函数的唯一返回值才有意义, 本例中, Promise就是duwenjian函数的返回值!!

Promise表示"承诺", 当异步完毕之后, 一定会执行resolve。

Promise.all()方法

Promise.all()方法接收一个Promise对象组成的数组作为参数, 当这个数组所有的Promise对象状态都变成resolved或者rejected的时候, 它才会去调用then方法。

function Async1(){
    return new Promise(function(resolve, reject){
    setTimeout(function(){
    console.log('异步任务1执行完成');
    resolve('数据1');
    }, 2000);
    });
}
function Async2(){
    return new Promise(function(resolve, reject){
    setTimeout(function(){
    console.log('异步任务2执行完成');
    resolve('数据2');
    }, 2000);
    });
}
function Async3(){
    return new Promise(function(resolve, reject){
    setTimeout(function(){
    console.log('异步任务3执行完成');
    resolve('数据3');
    //reject('出错了')
    }, 2000);
    });
}
//使用all方法执行多个异步函数
Promise.all([Async1(), Async2(), Async3()])
    .then((result)=>{
    console.log(result); //成功的结果
    })
    .catch((err)=>{
    console.log(err); //失败的结果
})

异步任务1执行完成

异步任务3执行完成

异步任务2执行完成

(3) ["数据1", "数据2", "数据3"]


Promise.race()

all方法的效果是「谁跑的慢, 以谁为准执行回调」

race方法的效果是「谁跑的快, 以谁为准执行回调」

这就是race方法, 这个词本来就是赛跑的意思。

race的用法与all一样, 我们把上面Async1延时改为1秒来看一下:

Promise.race([Async1(), Async2(), Async3()])
.then((result)=>{
console.log(result); //成功的结果
})
.catch((err)=>{
console.log(err); //失败的结果
})

这三个异步操作同样是并行执行的。结果你应该可以猜到, 1秒后Async1已经执行完了, 此时then里面的就执行了。

异步任务1执行完成

数据1

异步任务2执行完成

异步任务3执行完成

在then的回调开始执行时, Async2()和Async3()并没有停止, 仍旧在执行。于是再过1秒后, 输出了他们结束的标志。

这个race有什么用呢?使用场景还是很多的,比如可以用race给某个异步请求设置超时时间,并且在超时后执行相应的操作,代码如下:

//请求某个图片资源的函数

function requestImg(){
return new Promise(function(resolve, reject){
var img = new Image();
img.src = 'xxxxxx';
img.onload = function(){
resolve(img);
}
});
}
//延时函数,用于给请求计时
function timeout(){
return new Promise(function(resolve, reject){
setTimeout(function(){
reject('图片请求超时!');
}, 5000);
});
}
Promise.race([requestImg(), timeout()])
.then(function(result){
console.log(result);
})
.catch(function(err){
console.log(err);
});

总结:

Promise构造函数, 自己身上有all、race、reject、resolve等方法, 原型上有then、catch等方法。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表