学习Async和Promise
-
promise
-
主要用于异步计算
-
使异步操作队列化,按照期望得顺序执行,返回符合预期得结果
-
可以在对象之间传递和操作promise,帮助我们处理队列
-
两个特点
- 对象的状态不受外界影响。Promise 对象代表一个异步操作,有三种状态:Pending(进行中)、Resolved(已完成,又称 Fulfilled)和 Rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
- 一旦状态改变,就不会再变,任何时候都可以得到这个结果。
-
easy-example
new Promise(resolve => { setTimeout(() => { resolve('hello'); }, 2000); }).then(res => { console.log(res); },)
-
-
.then()
-
错误处理
new Promise((resolve, reject) => { setTimeout(() => { reject('bye'); }, 2000) }) .then((val) => { console.log(val) }, (err) => { console.log('Error:' + err); })
- 第二种
new Promise((resolve) => { setTimeout(() => { throw new Error('bye'); }, 2000) }).then((value) => { console.log(value); }).catch(error => { console.log('Error', error); })
- 多个then嵌套
new Promise(resolve => { console.log('step 1'); setTimeout(() => { resolve('100'); }, 1000) }).then(value => { // value = 100 return new Promise(resolve => { console.log('step-1-1'); setTimeout(() => { resolve('110'); }, 1000) }) }).then(value => { //value = 110 console.log('step-1-2'); return value; }).then(value => { // value = 110 console.log('step-1-3'); return value; // value = 110 }).then(value => { console.log(value); // value = 110 console.log('step 2'); })
- 运行结果
- catch() + then()错误处理
- 第一种
console.log('here we go...') new Promise(resolve => { setTimeout(() => { resolve(); }, 2000) }) .then(() => { console.log('start'); throw new Error('test error'); }) .catch(err => { console.log('I catch:', err); }) .then(() => { console.log('arrive here'); }) .then(() => { console.log('...and here'); }) .catch(err => { console.log('No, I catch:', err) })
- 运行结果
- 第二种
console.log('heoe we go..') new Promise(resolve => { setTimeout(() => { resolve(); }, 2000) }) .then(() => { console.log('start'); throw new Error('test error'); }) .catch(err => { console.log('1 catch: ', err); throw new Error('another error'); }) .then(() => { console.log('arrlve here'); }) .then(() => { console.log('...and here'); }) .catch(err => { console.log('No, I catch', err) })
- 运行结果
-
Promise.all () 批量执行
-
Promise.all([p1,p2,p3])用于将多个promise实例,包装成一个新的Promise实例,返回得实例就是普通得Promise它接收一个数组作为参数,可以不是数组,但必须具有 Iterator接口,数组里面可以是Promise对象,也可以是其他值,所有子Promise都完成,该Promise完成,返回值是全部值得数组,有任何一个失败,该Promise失败,返回值是第一个失败得子Promise结果
function cutUp() { console.log('开始切菜'); var p = new Promise(function (resolve, reject) { // 做一些异步操作 setTimeout(function () { console.log('切菜完毕'); }, 1000) }) return p; } // 烧水 function boil() { console.log('开始烧水'); var p = new Promise(function (resolve, reject) { // 做一些异步操作 setTimeout(function () { console.log('烧水完毕'); }, 1000) }) return p; } Promise.all([cutUp(), boil()]) .then((result) => { console.log(result); })
- 运行结果
- 注:all里面的promise实例会同时运行而不是按照顺序一个个运行
-
-
Promise.race ()
-
promise.finally( ()=>{ } )
- 用于指定不管 Promise 对象最后状态如何,都会执行的操作。
-
Promise.allSettled()
-
Promise.any()
-
Promise.resolve()
将现有对象转为 Promise 对象
let thenable = { then: function(resolve, reject) { resolve(42); } };
- 3.参数不是具有then方法的对象,或根本就不是对象
let p1 = Promise.resolve(thenable); p1.then(function(value) { console.log(value); // 42 });
- 4.不带有任何参数
const p = Promise.resolve('Hello'); p.then(function (s){ console.log(s) });
-
Promise.reject(reason)
- Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected。也就和resolve一样的。只不过这个是错误处理。
- 用于处理不知道函数是异步还是同步的时候,让函数按照原来的顺序执行 。
const f = () => console.log('Now'); Promise.resolve().then(f); console.log('next'); //但是还是提案 用不了,用了会说没有定义
const f = () => console.log('Now'); ( () => new Promise( resolve => resolve(f()) ) )(); //现在可以利用new一个promise时候就会执行的特点来执行try功能 console.log('next');
-
async 函数
async函数完全可以看作多个异步操作,包装成的一个 Promise 对象,而await命令就是内部then指令的语法糖。
- 基本语法
function timeout(ms) { return new Promise((resolve) => { setTimeout(resolve, ms); }); } async function asyncPrint(value, ms) { await timeout(ms); console.log(value); } asyncPrint('hello world', 50);
- async 函数有多种使用形式。
// 函数表达式 const foo = async function () {}; // 对象的方法 let obj = { async foo() {} }; obj.foo().then(...) // Class 的方法 class Storage { constructor() { this.cachePromise = caches.open('avatars'); } async getAvatar(name) { const cache = await this.cachePromise; return cache.match(`/avatars/${name}.jpg`); } } const storage = new Storage(); storage.getAvatar('jake').then(…); // 箭头函数 const foo = async () => {};
- async函数返回一个 Promise 对象
async function f() { return 'hello world'; } f().then(v => console.log(v))
async function f() { await Promise.reject('出错了'); } f() .then(v => console.log(v)) .catch(e => console.log(e)) // 出错了
- Await命令
- 正常情况下,await命令后面是一个 Promise 对象,返回该对象的结果。如果不是 Promise 对象,就直接返回对应的值。
- await命令后面是一个thenable对象(即定义then方法的对象),那么await会将其等同于 Promise 对象。
- 任何一个await语句后面的 Promise 对象变为reject状态,那么整
个async函数都会中断执行。async function f() { await Promise.reject('出错了'); await Promise.resolve(console.log(1)); // 不会执行 } f();
- 若不想中断两种方法
async function f() { try { await Promise.reject('出错了'); } catch(e) { } return await Promise.resolve('hello world'); } f() .then(v => console.log(v)) //
async function f() { await Promise.reject('出错了') .catch(e => console.log(e)); return await Promise.resolve('hello world'); } f() .then(v => console.log(v))
- 注意点
- 若不想中断两种方法
- 顶层await
- 允许在模块的顶层独立使用await命令。这个提案的目的,是借用await解决模块异步加载的问题 //依然只是一个提案
- 主要用在数据库的读取,import方法,让他们这些顶层同时执行。交出代码的执行权给其他的模块加载,等异步操作完成后,再拿回执行权,然后再继续向下执行。
// import() 方法加载 const strings = await import(`/i18n/${navigator.language}`); // 数据库操作 const connection = await dbConnector(); // 依赖回滚 let jQuery; try { jQuery = await import('https://cdn-a.com/jQuery'); } catch { jQuery = await import('https://cdn-b.com/jQuery'); }
- 总结一下:promise就是把原来复杂的回调函数简化了一哈,让函数看起来更加的容易读,方便维护,async和await就是一对,async可以来修饰函数,方法让他们成为一个promise实例。await是来执行那些promise函数的时候修饰用的。async和await就是promise的进阶版。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。