当前位置:威尼斯手机官网 > vnsc威尼斯城 > 将promise对象的状态由进行中—已失败
将promise对象的状态由进行中—已失败
2020-01-03

promise是什么?

Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。简单来说,promise的作用就是将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。

promise的特点

① 对象的状态不受外界影响:promise异步操作有三种状态:进行中,已成功,已失败。只有异步操作才能改变这个状态。 ②一变则不变:promise状态一旦改变,就不会再发生变化,promise对象改变的两种可能,进行中—已成功,进行中—已失败。

promise的基本用法

promise对象是一个构造函数,用来生成promise实例例子:

const promise = new Promise(function(resolve, reject) { // ... some code if (/* 异步操作成功 */){ resolve(value); } else { reject(error); }});

其中接受的参数是resolve和reject两个函数resolve的作用:将promise对象的状态由进行中—已完成。并将异步操作的结果作为参数传递出去rejected的作用:将promise对象的状态由进行中—已失败,并将异步失败的原因作为参数传递出去。注意:调用resolve或reject并不会终结promise的参数函数的执行例子:

new Promise((resolve, reject) = { resolve(1); console.log(2);}).then(r = { console.log(r);});// 2// 1

上面代码调用了resolve以后,后面的console(2)还是会执行,并且会首先打印出来。这是因为立即resolved的promise是在本轮事件循环的末尾执行,总是晚于本轮循环的同步任务。

then的用法

promise实例生成后,用then方法分别指定resolved状态和rejucted状态的回调函数。例子:

promise.then(function(value) { // success}, function(error) { // failure});

then方法可以接受两个回调函数作为参数,第一个回调函数是当promise对象状态是resolve的时候调用,第二个回调函数是当promise对象状态是reject的时候调用。如例子:

function timeout(ms) { return new Promise((resolve, reject) = { setTimeout(resolve, ms, 'done'); });}timeout(100).then((value) = { console.log(value);});// 结果是done

链式的then用法

then方法返回的是一个新的Promise实例。因此可以采用链式写法,即then方法后面再调用另一个then方法例子

getJSON("/post/1.json").then(function(post) { return getJSON(post.commentURL);}).then(function funcA(comments) { console.log("resolved: ", comments);}, function funcB(err){ console.log("rejected: ", err);});

上面代码中,第一个then方法指定的回调函数,返回的是另一个Promise对象。这时,第二个then方法指定的回调函数,就会等待这个新的Promise对象状态发生变化。如果变为resolved,就调用funcA,如果状态变为rejected,就调用funcB。

catch方法

promise对象中,如果异步操作抛出错误,状态就会变为rejected,就会调用catch方法指定的回调函数处理这个错误,另外,then方法指定的回调函数,如果运行中抛出错误也会被catch方法捕获。例子:

p.then((val) = console.log('fulfilled:', val)) .catch((err) = console.log('rejected', err));// 等同于p.then((val) = console.log('fulfilled:', val)) .then(null, (err) = console.log("rejected:", err));

promise对象的错误具有“冒泡”性质,会一直向后传,直到被捕获,也就是说,会跳过中间的then函数例子:

 getJSON('/post/1.json').then(function(post) { return getJSON(post.commentURL);}).then(function(comments) { // some code}).catch(function(error) { // 处理前面三个Promise产生的错误});

finally方法

finally方法用于指定不管promise对象最后状态如何,都会执行的操作。例子

server.listen(port) .then(function () { // ... }) .finally(server.stop);

例子是服务器使用promise处理请求,然后使用finally方法关掉服务器。

promise.all方法

promise.all方法用于将多个promise实例,包装成一个新的promise实例。比如:const p = Promise.all([p1, p2, p3]);Promise.all方法,接受的是一个数组作为参数,其中的元素都是promise实例,如果不是,则会自动将参数转变为promie实例。p的状态是有它的数组里面的元素决定的,分两种状态①只有p1 p2 p3的状态都变成fulfilled的状态才会变成fulfilled,此时p1 p2 p3的返回值组成一个数组,传递给p的回调函数。②只有p1 p2 p3之中,有一个被rejucted,p的状态就会变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。例子:

const p1 = new Promise((resolve, reject) = {resolve('hello');}).then(result = result);const p2 = new Promise((resolve, reject) = {throw new Error('报错了');}).then(result = result);Promise.all([p1, p2]).then(result = console.log(result)).catch(e = console.log(e));// Error: 报错了enter code here

promise.race()方法

Promise.race方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例

const p = Promise.race([p1, p2, p3]);

如果p1 p2 p3不是promise实例,也会自动转变成promise实例与promise.all不同的是,上面代码中,只用p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

async函数是什么

async的引入,使得异步操作变得更加方便,那async函数是什么,其实它是Generator函数的语法糖。使异步函数、回调函数在语法上看上去更像同步函数。Generator这里就不介绍了。我们直接来学习async

async的基本用法

async返回值是一个promise对象,因此可以使用then方法添加回调函数,当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的内容。例子:

async function getStockPriceByName(name) { const symbol = await getStockSymbol(name); const stockPrice = await getStockPrice(symbol); return stockPrice;}getStockPriceByName('goog').then(function (result) { console.log(result);});

async函数的使用形式

//函数声明async function foo(){}//函数表达式const foo = async function{};//对象的方法let obj = {async foo(){}};obj.foo().then(...)//class的方法class Storage{consttuctor{ 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 storage =new Storage();storage.getAvatar('jake').then(...)//箭头函数const foo =async()={};

async 函数内部return语句返回的值,会成为then方法调用函数的参数。例子:

async function getTitle(url) { let response = await fetch(url); let html = await response.text(); return html.match(/title([sS]+)/title/i)[1];}getTitle('').then(console.log)// "ECMAScript 2017 Language Specification"

await 命令

正常情况下,await命令后面跟着的是一个promise对象,如果不是会自动转化为promise对象例子:

async function f(){return await 123;}f().then(v =console.log(v))//123

当一个await语句后面的promise变为reject,那么整个函数都会中断执行。例子:

async function f() { await Promise.reject('出错了'); await Promise.resolve('hello world'); // 不会执行}

错误处理

如果await 后面的异步操作有错,那么等同于async函数返回的promis对象被reject 例子:

async function f() { await new Promise(function (resolve, reject) { throw new Error('出错了'); });}f().then(v = console.log(v)).catch(e = console.log(e))// Error:出错了

使用try ....catch代码块课防止出错。例子:

async function f() { try { await new Promise(function (resolve, reject) { throw new Error('出错了'); }); } catch(e) { } return await('hello world');}

也可以将多个await命令都放在try..catch结构中

async function main() { try { const val1 = await firstStep(); const val2 = await secondStep(val1); const val3 = await thirdStep(val1, val2); console.log('Final: ', val3); } catch (err) { console.error(err); }}

注意点

①await命令只能用在async函数中,用在普通函数中会报错。

下一篇:没有了