当前位置:K88软件开发文章中心编程语言JavaScriptECMAScript → 文章内容

ECMAScript 6 异步操作和Async函数

减小字体 增大字体 作者:佚名  来源:网上搜集  发布时间:2019-1-15 15:38:39

状态改变。也就是说,只有async函数内部的异步操作执行完,才会执行then方法指定的回调函数。下面是一个例子。async function getTitle(url) { let response = await fetch(url); let html = await response.text(); return html.match(/<title>([\s\S]+)<\/title>/i)[1];}getTitle('https://tc39.github.io/ecma262/').then(console.log)// "ECMAScript 2017 Language Specification"(3)正常情况下,await命令后面是一个Promise对象。如果不是,会被转成一个立即resolve的Promise对象。async function f() { return await 123;}f().then(v => console.log(v))// 123上面代码中,await命令的参数是数值123,它被转成Promise对象,并立即resolve。await命令后面的Promise对象如果变为reject状态,则reject的参数会被catch方法的回调函数接收到。async function f() { await Promise.reject('出错了');}f().then(v => console.log(v)).catch(e => console.log(e))// 出错了注意,上面代码中,await语句前面没有return,但是reject方法的参数依然传入了catch方法的回调函数。这里如果在await前面加上return,效果是一样的。只要一个await语句后面的Promise变为reject,那么整个async函数都会中断执行。async function f() { await Promise.reject('出错了'); await Promise.resolve('hello world'); // 不会执行}上面代码中,第二个await语句是不会执行的,因为第一个await语句状态变成了reject。为了避免这个问题,可以将第一个await放在try...catch结构里面,这样第二个await就会执行。async function f() { try { await Promise.reject('出错了'); } catch(e) { } return await Promise.resolve('hello world');}f().then(v => console.log(v))// hello world另一种方法是await后面的Promise对象再跟一个catch方面,处理前面可能出现的错误。async function f() { await Promise.reject('出错了') .catch(e => console.log(e)); return await Promise.resolve('hello world');}f().then(v => console.log(v))// 出错了// hello world如果有多个await命令,可以统一放在try...catch结构中。async function main() { try { var val1 = await firstStep(); var val2 = await secondStep(val1); var val3 = await thirdStep(val1, val2); console.log('Final: ', val3); } catch (err) { console.error(err); }}(4)如果await后面的异步操作出错,那么等同于async函数返回的Promise对象被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:出错了上面代码中,async函数f执行后,await后面的Promise对象会抛出一个错误对象,导致catch方法的回调函数被调用,它的参数就是抛出的错误对象。具体的执行机制,可以参考后文的“async函数的实现”。防止出错的方法,也是将其放在try...catch代码块之中。async function f() { try { await new Promise(function (resolve, reject) { throw new Error('出错了'); }); } catch(e) { } return await('hello world');}async函数的实现async 函数的实现,就是将 Generator 函数和自动执行器,包装在一个函数里。async function fn(args){ // ...}// 等同于function fn(args){ return spawn(function*() { // ... });}所有的async函数都可以写成上面的第二种形式,其中的 spawn 函数就是自动执行器。下面给出spawn函数的实现,基本就是前文自动执行器的翻版。function spawn(genF) { return new Promise(function(resolve, reject) { var gen = genF(); function step(nextF) { try { var next = nextF(); } catch(e) { return reject(e); } if(next.done) { return resolve(next.value); } Promise.resolve(next.value).then(function(v) { step(function() { return gen.next(v); }); }, function(e) { step(function() { return gen.throw(e); }); }); } step(function() { return gen.next(undefined); }); });}async函数是非常新的语法功能,新到都不属于 ES6,而是属于 ES7。目前,它仍处于提案阶段,但是转码器Babel和regenerator都已经支持,转码后就能使用。async 函数的用法async函数返回一个Promise对象,可以使用then方法添加回调函数。当函数执行的时候,一旦遇到await就会先返回,等到触发的异步操作完成,再接着执行函数体内后面的语句。下面是一个例子。async function getStockPriceByName(name) { var symbol = await getStockSymbol(name); var stockPrice = await getStockPrice(symbol); return stockPrice;}getStockPriceByName('goog').then(function (result) { console.log(result);});上面代码是一个获取股票报价的函数,函数前面的async关键字,表明该函数内部有异步操作。调用该函数时,会立即返回一个Promise对象。下面的例子,指定多少毫秒后输出一个值。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);上面代码指定50毫秒以后,输出"hello world"。Async函数有多种使用形式。// 函数声明async function foo() {}// 函数表达式const foo = async function () {};// 对象的方法let obj = { async foo() {} };// 箭头函数const foo = async () => {};注意点第一点,await命令后面的Promise对象,运行结果可能是rejected,所以最好把await命令放在try...catch代码块中。async function myFunction() { try { await somethingThatReturnsAPromise(); } catch (err) { console.log(err); }}// 另一种写法async function myFunction() { await somethingThatReturnsAPromise() .catch(function (err) { console.log(err); };}第二点,多个await命令后面的异步操作,如果不存在继发

上一页  [1] [2] [3] [4] [5] [6]  下一页


ECMAScript 6 异步操作和Async函数