资讯专栏INFORMATION COLUMN

从async await 报错Unexpected identifier 谈谈对上下文的理解

Bryan / 1421人阅读

摘要:解决办法,将箭头函数声明为函数,代码如下运行结果至此,问题解决。必须在函数的上下文中。对程序而言有了上下文调用帧才有一个完整的逻辑过程。

先简单介绍下async await:

  async/await是ES6推出的异步处理方案,目的也很明确:更好的实现异步编程。 详细见阮大神 ES6入门

现在说说实践中遇到的问题:使用await报错Unexpected identifier

先上代码:

var sleep = function (time) {
    return new Promise(function (resolve, reject) {
        setTimeout(function () {
            resolve(("999"));
        }, time);
    })
};
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
var start = async function(){
    arr.forEach(()=>{
        console.log( await sleep(2000) )
    })
}
start();

在循环中使用sleep方法,这时候报错:Unexpected identifier

原因:通过查资料发现一句话 await必须在async函数的上下文中。(后面重点讲)通过个人理解的这句话就是await只能在async函数中使用。

以上面的代码为例子,虽然最外层start函数是通过async声明的,在start函数体内部的箭头函数中使用了await,而该箭头函数是一个普通函数,所以await的上文是一个普通函数,最终导致报错。

解决办法,将箭头函数声明为async函数,代码如下:

var sleep = function (time) {
    return new Promise(function (resolve, reject) {
        setTimeout(function () {
            resolve(console.log("999"));
        }, time);
    })
};
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
var start = function(){
    arr.forEach(async ()=>{
        await sleep(2000)
    })
}
start();

运行结果:

至此,问题解决。

await必须在async函数的上下文中。----出处

上下文,英文context,其完整意思应当是concatenate-text,联系文本,编程中翻译为“引用池”或者“引用区”更加恰当。----百度百科

先举个例子:

③.小明说:重启试试

单从这句话我们不能知道重启什么、为什么小明要说这句话(可能你觉得是电脑)、对谁说的这句话

②.小红说对小明说她微信出来不了输入法

这就是小明为什么说这句话的上文(背景),这时候才能知道小明说的重启是微信程序or手机(真不是电脑)

①.小红和小明躺在床上玩手机

这句也是背景,但是却不能成为③的上文,因为“躺床上”并不是“重启试试”的原因(或者说背景)

函数调用会在内存形成一个"调用记录",又称"调用帧"(call frame),保存调用位置和内部变量等信息

个人理解:上文指出了环境、背景。

拿本文中的第一段错误代码来说,await的上文是一个普通箭头函数,所以使用await会报错,因为编译器在执行到await时,当前调用帧是箭头函数而不是外层的start,所以此时的await就像:小明和小红躺在床上 小明说“重启试试” ,是无意义(Unexpected identifier)的。

这时候谈谈下文,接上面的例子

④.小红重启了手机

④就是③的下文

上下文结合在一起才能构建一个完整的逻辑
比如④和③就是上下文,我们才能将其联系起来,如果只有④或者④和②,从逻辑上来说都不是完整的。
对程序而言 有了上下文“调用帧”才有一个完整的逻辑过程。计算机才知道下一步该去哪,该回到哪。

需要注意的是,上下文是一个整体,上面将其分开只是为了理解,实际过程中,不存在多带带的上文和下文,所以这是await 必须在async 的上下文 的具体意义。

原文首发地址:http://www.cnblogs.com/lonhon...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/91783.html

相关文章

  • ES6系列文章 异步神器async-await

    摘要:有两个陌生的关键字,同时函数执行结果似乎返回了一个对象。用来表示函数是异步的,定义的函数会返回一个对象,可以使用方法添加回调函数。如果的是对象会造成异步函数停止执行并且等待的解决如果等的是正常的表达式则立即执行。 视频讲解 关于异步处理,ES5的回调使我们陷入地狱,ES6的Promise使我们脱离魔障,终于、ES7的async-await带我们走向光明。今天就来学习一下 async-a...

    miqt 评论0 收藏0
  • 重构:Promise到Async/Await

    摘要:一方面,这里替代的是异步代码的编写方式,并非完全抛弃大家心爱的,地球人都知道是基于的,不用太伤心另一方面,是基于回调函数实现的,那也没有替代回调函数咯重构代码之后,我仍然用到了库。 摘要: 夸张点说,技术的发展与历史一样,顺之者昌,逆之者亡。JS开发者们,赶紧拥抱Async/Await吧! GitHub仓库: Fundebug/promise-asyncawait 早在半年多之前,...

    zhangfaliang 评论0 收藏0
  • JavaScript闯关笔记

    摘要:对空数组是不会执行回调函数的。就算改变已经发生了,你再对对象添加回调函数,也会立即得到这个结果。用来表示函数是异步的,定义的函数会返回一个对象,可以使用方法添加回调函数。 介绍 通过Array/Object/Function基础类型编写。 看到自己不了解的或者比较新颖的用法便会写上。 不定时更新内容。 本文首发于我的个人网站: Timbok.top 目录 Array 迭代方法 ...

    Jokcy 评论0 收藏0
  • ES6—Async与异步编程(11)

    摘要:所以异步编程对语言太重要。异步编程我们就以用户注册这个特别常见的场景为例,讲讲异步编程。这种层层嵌套被称为回调地狱。相比回调函数而言,代码可读性更高,代码的执行顺序一目了然。函数内部语句返回的值,会成为方法回调函数的参数。 单线程是Javascript语言最本质的特性之一,Javascript引擎在运行js代码的时候,同一个时间只能执行单个任务。 这种模式的好处是实现起来比较简单,执行...

    chengjianhua 评论0 收藏0
  • 【面试篇】寒冬求职季之你必须要懂原生JS(中)

    摘要:如果你还没读过上篇上篇和中篇并无依赖关系,您可以读过本文之后再阅读上篇,可戳面试篇寒冬求职季之你必须要懂的原生上小姐姐花了近百个小时才完成这篇文章,篇幅较长,希望大家阅读时多花点耐心,力求真正的掌握相关知识点。 互联网寒冬之际,各大公司都缩减了HC,甚至是采取了裁员措施,在这样的大环境之下,想要获得一份更好的工作,必然需要付出更多的努力。 一年前,也许你搞清楚闭包,this,原型链,就能获得...

    andycall 评论0 收藏0

发表评论

0条评论

Bryan

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<