Promise和Async/Await用法整理

1.Promise

1.简介

Promise,简单来说就是一个容器,里面保存着某个未来才会结束的时间(通常是一个异步操作的结果)

Promise对象的基本语法:

new Promise((resolve,reject) => {
    //.....
});

从语法上来说,Promise是一个对象,从它可以获取异步操作的消息。

基本语法:

let p = new Promise((resolve,reject) => {
    //...
    resolve('success')
});

p.then(result => {
    console.log(result);//success
});

Promise对象特点和三个状态:

例如:

let p = new Promise((resolve,reject) => {
    //...
    resolve('success');
    console.log('after resolve');
    reject('error');
});

p.then(result => {
    console.log(result);
});

p.catch(result => {
    console.log(result);
})

运行结果:
after resolve
success

resolve下面的语句其实是可以执行的,那么为什么reject的状态信息在下面没有接受到呢?这就是因为Promise对象的特点:状态的凝固。new出一个Promise对象时,这个对象的起始状态就是Pending状态,在根据resolve或reject返回Fulfilled状态/Rejected状态。

2.

Then分别接受resolve和reject的信息,有三种参数形式,第三种比较“怪异”,只用来接收做reject处理。

eg:

let p = new Promise((resolve,reject) => {
    //...
    let random = Math.random();//小于1大于0
    if(random > 0.4) {
        resolve('random > 0.4');
    }else {
        reject('random <= 0.4');
    }
});

p.then(result => {
    console.log('resolve',result);
}, result => {
    console.log('reject',result);
});

3.链式调用

我们来执行一段代码:

let p = new Promise((resolve,reject) => {
    reject('reject');
});

let resultP = p.then(null,result => {
    console.log(result);
});

console.log(resultP);

结果:
Promise { }
reject

js的执行顺序就是这样,同步->异步->回调,在同步执行的时候,Promise对象还处于pending的状态,也说明了这个then返回的是一个Promise对象。

而且必须在then里面给一个返回值,才能继续调用,否则undefined。
eg:

let p = new Promise((resolve,reject) => {
    reject('error');
});

let resultP = p.then(null,result => {
    console.log(result);
    return 123;
});

// console.log(resultP);
resultP.then(tmp => {
    console.log(tmp);
})

结果:
error
123

4.catch

eg:

let p = new Promise((resolve,reject) => {
    reject('error');
});

p.catch(result => {
    console.log(result);
})

那这个catch的返回值是什么呢:
和上面then是一样的。

5.Promise.resolve()

传一个普通的对象:

// let p1 =Promise.resolve(123);
let p1 =Promise.resolve({name:'xixi',age:'xxxx'});

p1.then(result => {
    console.log(result);
});

如果是Promise对象呢,直接返回

let p = new Promise((resolve,reject) => {
    setTimeout(() => {
        resolve('success');
    },500);
});

let pp = Promise.resolve(p);

pp.then(result => {
    console.log(result);
});

console.log(pp == p);

结果:
true
success

6.Promise.reject()

eg:

let p = Promise.reject(123);

console.log(p);

p.then(result => {
    console.log(result);
}).catch(result => {
    console.log('catch',result);
})

结果:
Promise { 123 }
catch 123

7.Promise.all()

eg:

let p1 = Promise.resolve(123);
let p2 = Promise.resolve('hello');
let p3 = Promise.resolve('success');

Promise.all([p1,p2,p3]).then(result => {
    console.log(result);
})

结果:
[ 123, ‘hello‘, ‘success‘ ]

成功之后就是数组类型,当所有状态都是成功状态才返回数组,只要其中有一个的对象是reject的,就返回reject的状态值。
eg:

let p1 = Promise.resolve(123);
let p2 = Promise.resolve('hello');
let p3 = Promise.resolve('success');
let p4 = Promise.reject('error');

// Promise.all([p1,p2,p3]).then(result => {
//     console.log(result);
// });

Promise.all([p1,p2,p4]).then(result => {
    console.log(result);
}).catch(result => {
    console.log(result);
});

结果:
error

又一个eg:

//用sleep来模仿浏览器的AJAX请求
function sleep(wait) {
    return new Promise((res,rej) => {
        setTimeout(() => {
            res(wait);
        },wait);
    });
}

let p1 = sleep(500);
let p2 = sleep(500);
let p3 = sleep(1000);

Promise.all([p1,p2,p3]).then(result => {
    console.log(result);
    //.....
    //loading
});

8.Promise.race

和all同样接受多个对象,不同的是,race()接受的对象中,哪个对象返回的快就返回哪个对象,就如race直译的赛跑这样。如果对象其中有reject状态的,必须catch捕捉到,如果返回的够快,就返回这个状态。race最终返回的只有一个值。
eg:

//用sleep来模仿浏览器的AJAX请求
function sleep(wait) {
    return new Promise((res,rej) => {
        setTimeout(() => {
            res(wait);
        },wait);
    });
}

let p1 = sleep(500);
let p0 = sleep(2000);

Promise.race([p1,p0]).then(result => {
    console.log(result);
});

let p2 = new Promise((resolve,reject) => {
    setTimeout(()=>{
        reject('error');
    },1000);
});

Promise.race([p0,p2]).then(result => {
    console.log(result);
}).catch(result => {
    console.log(result);
});

500
error

9.异常处理

为什么说安静,一个例子,Pormise内部的错误外界用try-catch捕捉不到
eg:

try {
    let p = new Promise((resolve, reject) => {
        throw new Error("I'm error");
        // reject(new Error("I'm Error"));
    });
}catch(e) {
    console.log('catch',e);
}

结果什么都没打印。
但是抛出的错误可以通过catch来捕捉:

// try {
    let p = new Promise((resolve, reject) => {
        throw new Error("I'm error");
        // reject(new Error("I'm Error"));
    });
// }catch(e) {
//     console.log('catch',e);
// }

p.catch(result => {
    console.log(result);
});

这样就捕捉到错误。所以:

2.Async-Await

1.简介:

async和await在干什么,async用于申明一个function是异步的,而await可以认为是async wait的简写,等待一个异步方法执行完成。

2.基本语法


在Chrome里申明这样一个函数,可以在控制台看到返回的其实就是一个Promise对象。
扩展需要了解的就是Chrome现在也支持asyncFunction,可以在Chrome控制台测试:
console.log(async function(){}.constructor);
? AsyncFunction() { [native code] }

3.规则

如图,await放在普通函数里是会报错的。

eg:

async function demo() {
    let result = await Promise.resolve(123);
    console.log(result);
}
demo();

4.应用

Promise虽然一方面解决了callback的回调地狱,但是相对的把回调“纵向发展”了,形成了一个回调链。eg:

function sleep(wait) {
    return new Promise((res,rej) => {
        setTimeout(() => {
            res(wait);
        },wait);
    });
}

/*
let p1 = sleep(100);
let p2 = sleep(200);
let p =*/

sleep(100).then(result => {
    return sleep(result + 100);
}).then(result02 => {
    return sleep(result02 + 100);
}).then(result03 => {
    console.log(result03);
})

控制台:
300

后面的结果都是依赖前面的结果。
改成async/await写法就是:

async function demo() {
    let result01 = await sleep(100);
    //上一个await执行之后才会执行下一句
    let result02 = await sleep(result01 + 100);
    let result03 = await sleep(result02 + 100);
    // console.log(result03);
    return result03;
}

demo().then(result => {
    console.log(result);
});

因为async返回的也是promise对象,所以用then接受就行了。
结果:
300
需要注意的就是await是强制把异步变成了同步,这一句代码执行完,才会执行下一句。

5.错误处理

如果是reject状态,可以用try-catch捕捉
eg:

let p = new Promise((resolve,reject) => {
    setTimeout(() => {
        reject('error');
    },1000);
});

async function demo(params) {
    try {
        let result = await p;
    }catch(e) {
        console.log(e);
    }
}

demo();

结果:
error
这是基本的错误处理,但是当内部出现一些错误时,和上面Promise有点类似,demo()函数不会报错,还是需要catch回调捕捉。这就是内部的错误被“静默”处理了。

let p = new Promise((resolve,reject) => {
    setTimeout(() => {
        reject('error');
    },1000);
});

async function demo(params) {
    // try {
        let result = name;
    // }catch(e) {
    //     console.log(e);
    // }
}

demo().catch((err) => {
    console.log(err);
})

6.注意你的并行执行和循环

比如上面的例子:

如果这三个是你想异步发出的AJAX请求,在这段代码里其实是同步的,第一个发出去才会发第二个,所以async/await需要谨慎使用。

现在有一些forEach或者map的循环里,比如在forEach里使用await,这时候的上下文就变成了array,而不是async function,就会报错。这时候你就要想到是什么错误。

原文地址:https://www.cnblogs.com/zhangmingzhao/p/8343685.html

时间: 2024-08-07 10:55:17

Promise和Async/Await用法整理的相关文章

node.js异步控制流程 回调,事件,promise和async/await

写这个问题是因为最近看到一些初学者用回调用的不亦乐乎,最后代码左调来又调去很不直观. 首先上结论:推荐使用async/await或者co/yield,其次是promise,再次是事件,回调不要使用. 接下来是解析,为什么我会有这样的结论 首先是回调,理解上最简单,就是我把任务分配出去,当你执行完了我就能从你那里拿到结果执行相应的回调, 这里演示一个对setTimeout的封装,规定时间后打印相应结果并执行回调函数 并且这个函数传给回调函数的参数符合node标准,第一个为error信息,如果出错e

callback vs async.js vs promise vs async / await

需求: A.依次读取 A|B|C 三个文件,如果有失败,则立即终止. B.同时读取 A|B|C 三个文件,如果有失败,则立即终止. 一.callback 需求A: let read = function (code) { if (code) { return true; } else { return false; } } let readFileA = function (callback) { if (read(1)) { return callback(null, "111");

promise和async/await的用法

promise和async都是做异步处理的, 使异步转为同步 1.promise 它和Promise诞生的目的都是为了解决“回调地狱”, promise使用方法: <button @click="testBtn()">点击</button> get(data) { return new Promise((resolve, reject)=>{ if (data > 5) { resolve(data); } else { reject("数

js中回调函数,promise 以及 async/await 的对比用法 对比!!!

在编程项目中,我们常需要用到回调的做法来实现部分功能,那么在js中我们有哪些方法来实现回调的? 方法1:回调函数 首先要定义这个函数,然后才能利用回调函数来调用! login: function (fn) { var app = getApp() wx.login({ success: res => { let code = res.code; wx.getSetting({ success: res => { if (res.authSetting['scope.userInfo']) {

重构:从Promise到Async/Await

摘要: 夸张点说,技术的发展与历史一样,顺之者昌,逆之者亡.JS开发者们,赶紧拥抱Async/Await吧! GitHub仓库: Fundebug/promise-asyncawait 早在半年多之前,我就在鼓吹Async/Await替代Promise的6个理由,似乎还招致了一些批评.然而,直到最近,我才真正开始进行代码重构,抛弃Promise,全面使用Async/Await.因为,Node 8终于LTS了! Async/Await真的比Promise好吗? 是的是的. 这些天,我大概重构了10

异步 callback vs promise vs async/await

1. callback var fn1=function(){console.log("func1")} var fn2=function(fn){ setTimeout(function(){ console.log("func2") fn() //不能写fn,这只是函数名,要写fn()才是触发 },500)}var fn3=function(){console.log("func3")} //函数名作为参数传入fn2 fn1()fn2(fn3

用promise和async/await分别实现红绿灯

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" con

Promise和async/await

1.promise对象 promise 对象有三种状态:pending(进行中).fulfilled(已成功)和 rejected(已失败).promise 对象的状态改变,只有两种可能:从 pending 变为 fulfilled 和从 pending 变为 rejected. const promise = new Promise(function(resolve, reject) { if (){ resolve(value); } else { reject(error); } });

promise 和 async await比较

async搭配await是ES7提出的,它的实现是基于Promise.这里使用它对比Promise的用法,这里只是简单的适合日常业务的使用场景. async.await是ES7中的提案,通过同步方式的写法,使得代码更容易阅读. 注意:await函数不能单独使用,而且async函数返回的是一个Promise对象,可以使用then函数添加回调函数.当函数执行的时候,一旦遇到await函数就会先返回一个Promise对象,等到异步操作完成,再去执行后面的语句.如果 await 后面的异步操作出错,那么