资讯专栏INFORMATION COLUMN

javascript异步编程(一)-现状

huashiou / 1997人阅读

写在前面, 这个话题其实还挺大的, 我自己恐怕力有不逮, 所以只能算是笔记总结, 写的肯定会有点简略. 有错误实在太正常了. 希望能多多指教.

这篇文章仅仅是解释一下现有的异步编程方案不涉及具体原理, 但是我的想法是试试看能不能每个方案都自己实现一遍, 所以可能是系列文章也可能就此太监了.

回调函数

想必大家都看过上面的图片, 虽然不是js代码, 甚至不是回调, 但是各位同学估计对callback hell感同身受. 但是事实上回调函数跟异步编程并没有必然的联系. 回调只是一种设计模式. 同步代码同样可以使用回调只是大部分时候会让人觉得多此一举而已.

大家都知道回调并不是那么优雅, 很多时候代码可能写成这样:

asyncJob1(function () {
  asyncJob2(function () {
    asyncJob3(function () {
      // your code
    })
  })
})

虽然问题算是解决了吧, 但是代码看着真是令人头痛. 玩意逻辑稍微复杂一点说不定真会出现下面的情况:

大概美军也是回调写多了吧2333.

事件驱动

大部分gui程序都是采用事件驱动, web当然也不例外, 最典型的就是dom事件:

div.on("click", function () {
  // balabala
})

这个几乎都是跟回调和事件循环相关的, 后面会详细讲到的.

Promise

根据promise/A+的规范:

一个Promise必须处在其中之一的状态:pending, fulfilled 或 rejected.
如果是pending状态,则promise可以转换到fulfilled或rejected状态。
如果是fulfilled状态,则promise不能转换成任何其它状态。
如果是rejected状态,则promise不能转换成任何其它状态。

Promise都会有个then方法, 制定了fulfilled和rejected两种请况的回调, 同时then会返回一个Promise对象, 这就允许我们链式调用了:

ajax("xxx").then(res => res).then(res => res)

虽然Promise的方案比回调已经好太多了. 但是不难发现多个then其实未必比回调好看太多, 只能说把回调铺平了. 可能Promise并不是最优雅的解决方案.

generator

generator在各个语言里都有出现, python,c#等, 这里不说概念, 只说在js里该怎么使用就行, 基本理解就是generator是拥有多个返回值的函数, 每次调用next就会调用一次返回. 这就是所谓 控制权移交, 当然这样不足以体现其优越性, generator最重要的特性就是分步数据传递: next的参数可以作为上次yield的返回值, 其实直觉上不是很能理解, 不过我们这里只要知道有这么个东西就成, 下面是代码示例:

var f = function* (x) {
    var y = yield x + 1
    yield y + 1
    return y
}


var t = f(1)

var s = t.next()
console.log(s) // 2
var p = t.next(4) // 这里的4作为上次yield的返回值
console.log(p) // 5

有这么一个特性, 那么下面的操作性就很强了, 比如tj的著名的co:

co(function* () {
  var result = yield Promise.resolve(true);
  return result;
}).then(function (value) {
  console.log(value);
}, function (err) {
  console.error(err.stack);
});

可以说写法已经很同步了. 当然这个也不是最终的解决方案, 不然为什么koa2要用async/await呢hhh

async/await

同样对于async/await 我们先不纠结其原理, 我们只需要知道它是generator和promise二者结合起来的语法糖(不过也真够甜的)

每个async必然返回一个Promise对象, 所以async会像瘟疫一个把你的每个函数都变成async函数, 所谓可以async的终将async, 下面是例子:

// Promise的解决方案
function foo () {
  return ajax("xxx").then(res => res).then(res => res)
}


async function bar () {
  try {
    const response = await ajax("xxx")
    console.log(response)
  } catch (e) {
    throw e
  }
}

是不是优雅了太多, 除了一大片async/await, 不过也算小小的代价.

利用午休时间码了出来, 不知道有多少错误呢hhh

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

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

相关文章

  • 前端每周清单半年盘点之 JavaScript

    摘要:前端每周清单专注前端领域内容,以对外文资料的搜集为主,帮助开发者了解一周前端热点分为新闻热点开发教程工程实践深度阅读开源项目巅峰人生等栏目。背后的故事本文是对于年之间世界发生的大事件的详细介绍,阐述了从提出到角力到流产的前世今生。 前端每周清单专注前端领域内容,以对外文资料的搜集为主,帮助开发者了解一周前端热点;分为新闻热点、开发教程、工程实践、深度阅读、开源项目、巅峰人生等栏目。欢迎...

    Vixb 评论0 收藏0
  • 2017-06-27 前端日报

    摘要:前端日报精选漫谈函数式编程一十年踪迹的博客前端每周清单的优势与劣势有望超越在嵌入式及物联网的应用现状进阶系列高阶组件详解一前端之路译如何充分利用控制台掘金程序猿升级攻略众成翻译中文译如何充分利用控制台掘金前端从强制开启压缩探 2017-06-27 前端日报 精选 漫谈 JS 函数式编程(一) - 十年踪迹的博客前端每周清单: Vue的优势与劣势;Node.js有望超越Java;JS在嵌...

    Eidesen 评论0 收藏0
  • 前端知识点整理

    摘要:难怪超过三分之一的开发人员工作需要一些知识。但是随着行业的饱和,初中级前端就业形势不容乐观。整个系列的文章大概有篇左右,从我是如何成为一个前端工程师,到各种前端框架的知识。 为什么 call 比 apply 快? 这是一个非常有意思的问题。 作者会在参数为3个(包含3)以内时,优先使用 call 方法进行事件的处理。而当参数过多(多余3个)时,才考虑使用 apply 方法。 这个的原因...

    Lowky 评论0 收藏0
  • 前端知识点整理

    摘要:难怪超过三分之一的开发人员工作需要一些知识。但是随着行业的饱和,初中级前端就业形势不容乐观。整个系列的文章大概有篇左右,从我是如何成为一个前端工程师,到各种前端框架的知识。 为什么 call 比 apply 快? 这是一个非常有意思的问题。 作者会在参数为3个(包含3)以内时,优先使用 call 方法进行事件的处理。而当参数过多(多余3个)时,才考虑使用 apply 方法。 这个的原因...

    snowLu 评论0 收藏0
  • 双十二大前端工程师读书清单

    摘要:本文最早为双十一而作,原标题双大前端工程师读书清单,以付费的形式发布在上。发布完本次预告后,捕捉到了一个友善的吐槽读书清单也要收费。这本书便从的异步编程讲起,帮助我们设计快速响应的网络应用,而非简单的页面。 本文最早为双十一而作,原标题双 11 大前端工程师读书清单,以付费的形式发布在 GitChat 上。发布之后在读者圈群聊中和读者进行了深入的交流,现免费分享到这里,不足之处欢迎指教...

    happen 评论0 收藏0

发表评论

0条评论

huashiou

|高级讲师

TA的文章

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