Promise
概述
promise是异步编程的一个解决方案,它是一个对象,创建方式与普通对象相同。可以通过promise构造函数创建出来,从他可以获取异步操作的消息.
promise有三种状态:进行中,已完成,已失败
Promise是一个构造器,原型上有then,catch方法,对象上有reject、resolve方法。
创建
通过new关键字创建promise对象
var p = new Promise(function(resolve, reject){
// 做一些异步操作
setTimeout(function(){
console.log('执行完成');
resolve('随便什么数据');
}, 2000);
});
resolve
resolve:异步操作执行成功后的回调函数
let p = new Promise((resolve, reject) => {
let n = 1;
console.log(n);
if (n > 2) {
resolve('666');
} else {
reject('error');
}
})
p.then(value => {
console.log(value)
}, reason => {
console.log(reason)
})
reject
reject:异步操作执行失败后的回调函数
事实上,我们前面的例子都是只有“执行成功”的回调,还没有“失败”的情况,reject的作用就是把Promise的状态置为rejected,这样我们在then中就能捕捉到,然后执行“失败”情况的回调。
const pro = new Promise((resolve, reject) => {
reject('1111');
})
pro.then((val) => {
console.log('then方法中的第一个参数被执行了');
console.log(val);
}, (err) => {
console.log('then方法中的第二个参数被执行了');
console.log(err);
})
then
promise.then()方法会返回一个新的promise对象 在then中进行return 会被新的promise对象的then捕获
function getPromise() {
return new Promise((resolve) => {
setTimeout(function() {
console.log('异步操作执行完成');
resolve('执行成功1');
}, 1000);
})
}
const pro1 = getPromise();
pro1.then((v) => {
console.log(v);
return '执行成功2';
}).then((v) => {
console.log(v);
return '执行成功3';
}).then((data) => {
console.log(data);
})
.then中的第一个函数被触发 一定是resolve方法调用 而且代码逻辑没有出错
.then中的第二个函数被触发的情况:
- resolve参数中有错误代码 (无论有无resolve() || reject())
- reject方法被调用
resolve之后的代码不会被捕获
- resolve()/ reject()之后的代码逻辑上有错误 不会被.then中的第二个参数函数捕获 也不会报错
- resolve之后的代码逻辑上没有问题,就会有执行
catch
们知道Promise对象除了then方法,还有一个catch方法,它是做什么用的呢?其实它和then的第二个参数一样,用来指定reject的回调,用法是这样:
getNumber();
.then(function(data){
console.log('resolved');
console.log(data);
}).catch(function(reason){
console.log('rejected');
console.log(reason);
});
效果和写在then的第二个参数里面一样。不过它还有另外一个作用:在执行resolve的回调(也就是上面then中的第一个参数)时,如果抛出异常了(代码出错了),那么并不会报错卡死js,而是会进到这个catch方法中。
getNumber()
.then(function(data){
console.log('resolved');
console.log(data);
console.log(somedata); //此处的somedata未定义
})
.catch(function(reason){
console.log('rejected');
console.log(reason);
});
在resolve的回调中,我们使用了console.log(somedata);而somedata这个变量是没有被定义的。如果我们不用Promise,代码运行到这里就直接在控制台报错了,不往下运行了。但是在这里,会得到这样的结果:
也就是说进到catch方法里面去了,而且把错误原因传到了reason参数中。即便是有错误的代码也不会报错了,这与我们的try/catch语句有相同的功能。
all
- Promise.all() 方法用于将多个 Promise 实例, 包装成一个新的 Promise 实例。
- 语法:const p = Promise.all([p1, p2, p3]);
- 只有p1、 p2、 p3的状态都变成fulfilled, p的状态才会变成fulfilled
- 只要p1、 p2、 p3之中有一个被rejected, p的状态就变成rejected
const p1 = new Promise((res, rej) => {
res(1);
})
const p2 = new Promise((res, rej) => {
res(2);
})
const p3 = new Promise((res, rej) => {
res(3);
});
const p = Promise.all([p1, p2, p3]);
console.log(p);
p.then((v) => {
console.log(v);
}).catch((err) => {
console.log(err);
})
finally
- finally()方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。
- finally方法的回调函数不接受任何参数
new Promise((reso, reje) => {
reso(1);
}).then((val) => {
console.log(val);
}).catch((err) => {
console.log(err);
}).finally(() => {
console.log('一定会执行的代码');
})
async函数
async
- 语法
async function name(param) { statements }
参数说明:
- name: 函数名称。
- param: 要传递给函数的参数的名称。
- statements: 函数体语句。
- 返回值
async 函数返回一个 Promise 对象,可以使用 then 方法添加回调函数。
async function fn() {
// return '函数的返回值';
console.log(x);
}
var res = fn();
console.log(res);
res.then(v => {
console.log(v);
}).catch(err => {
console.log(err, 6666);
})
await
async 函数中可能会有 await 表达式,async 函数执行时,如果遇到 await 就会先暂停执行 ,等到触发的异步操作完成后,恢复 async 函数的执行并返回解析值。
await 操作符用于等待一个 Promise 对象, 它只能在异步函数 async function 内部使用。如果在 async function 函数体外使用 await ,你只会得到一个语法错误。
- 语法:
[return_value] = await expression;
参数说明:
- expression: 一个 Promise 对象或者任何要等待的值。
- 返回值
返回 Promise 对象的处理结果。如果等待的不是 Promise 对象,则返回该值本身。
如果一个 Promise 被传递给一个 await 操作符,await 将等待 Promise 正常处理完成并返回其处理结果。
正常情况下,await 命令后面是一个 Promise 对象,它也可以跟其他值,如字符串,布尔值,数值以及普通函数。(await加普通函数其实就是和不加一样效果) - await针对所跟不同表达式的处理方式:
- Promise 对象:await 会暂停执行,等待 Promise 对象 resolve,然后恢复 async 函数的执行并返回解析值。
- 非 Promise 对象:直接返回对应的值。
示例1: await后面是一个Promise对象(函数调用结果):
function testAwait() {
return new Promise((resolve, reject)=>{
setTimeout(()=>{
console.log("返回一个promise对象");
resolve("返回数据"); // 如果没有resolve(),代表这个promise没有执行完成 那么下面的helloAsync函数内部的代码也会阻塞,不会继续往下执行
}, 2000)
});
}
async function helloAsync() {
console.log('helloAsync开始执行')
var a = await testAwait();
console.log(a);
console.log('helloAsync结束执行')
}
helloAsync();
// 执行结果:
// 返回一个promise对象
// 返回数据
// helloAsync
async function haha(){
await new Promise(function(res,rej){
setTimeout(function(){
console.log(1);
res(123123)
},2000)
})
console.log(2);
}
haha();
// 1 2
示例2:await后面是一个普通值
async function myAsync() {
var res = await 111;
console.log(res); // 111
}
myAsync();
function createPromise() {
return new Promise((resolve, reject) => {
setTimeout(function() {
console.log('请求成功');
const data = new Array(10).fill({ name: 'Florence', employee: '前端开发工程师' });
resolve(data);
}, 2000)
})
}
async function fn() { // async标识的函数返回值是一个promise对象 函数的return值将会被then接收
console.log('async执行了');
// const res = createPromise();
const res = await createPromise();
console.log(res);
return 666;
}
let fn_res = fn();
fn_res.then((val) => {
console.log(val); // 666
}).catch((err) => {
console.log(err);
})
标签:function,异步,resolve,console,log,res,Promise
From: https://www.cnblogs.com/Kongqingzhi/p/16633692.html