当前位置: 首页 > news >正文

网站界面设计套题辅导班

网站界面设计套题,辅导班,中国机械加工网价位,南京淄博网站建设工作室AsynchronousJS 异步编程极简史,这个故事网上已经很多人有了自己的讲述。Event Loop 解释了 Node.js 为何以及如何实现单线程服务模型和 Event Loop。对于 JS 开发者来说,我们大多数时候并不需要关心底层是如何实现异步操作的,但是我们需要了…

Asynchronous

JS 异步编程极简史,这个故事网上已经很多人有了自己的讲述。

Event Loop 解释了 Node.js 为何以及如何实现单线程服务模型和 Event Loop。对于 JS 开发者来说,我们大多数时候并不需要关心底层是如何实现异步操作的,但是我们需要了解如何进行异步编程。 JS 天然的被设计成单线程,事件循环是 JS 非常重要的特性,异步编程极其重要。

Callback

A callback is a function that is passed as an argument to another function and is executed after its parent function has completed.

JS 通过给异步操作提供一个 Callback 回调函数,当异步任务执行完成后使用操作结果(成功或失败)调用 Callback 函数,这样就可以拿到异步操作的结果。

Libuv(I/O、Timer等) —> Event Loop —> Callback 处理异步结果

setTimeout(function (msg) { // 匿名callback函数,一秒后被调用。console.log(msg); // 拿到了异步结果。
}, 1000, 'hello');

Callback Hell

Node.js 的出现,使得 JS 从前端开发登上了后端开发的舞台。后端开发涉及的场景更加复杂多样,前端主要是使用 Ajax 调用后端接口,而后端则需要处理更多的业务逻辑,比如是微服务则需要更多的服务通讯。由于 JS 天然就是为浏览器端设计的,所以 JS 暴露出来的问题就越来越明显。异步处理就是其中一个经常遇到的问题,开发者往往陷入 Callback Hell 无法自拔。

当异步操作比较多或复杂(比如一个函数中包含多个网络请求),需要等前一个异步操作结束后在 Callback 中继续执行下一个异步操作,如此类推,就出现了Callback嵌套,也就是 Callback Hell。

a8b87de2a17f2593eee1e804d3cc7e6b.png

异步操作之间的关系分为两种:

  1. 异步操作之间有前后依赖关系(串行),也就是第一个异步操作要执行完成再能继续执行下一个异步操作。比如获取某个用户收藏的文件:先执行异步操作从藏表获取用户收藏的文件,然后根据收藏的文件异步操作从数据库把文件列表取出来。
  2. 异步操作之间没有前后依赖关系,也就是可以并发/并行执行,它们相互之间没有影响。比如发送邮件通知,同时发送给一百个或一万个用户之间是没有影响的,可以并发进行提高效率。

对于情况1,会产生 Callback 嵌套。对于情况二,也只能使用 Callback 嵌套处理,因为 Callback 无法保证同时并发处理多个异步操作,且在异步操作全部结束后拿到全部的结果。这就意味着 Callback 会失去批量并发处理异步请求的更高效率。

虽然使用 Callback 解决了异步编程的处理异步操作结果的问题,但是带来了 Callback Hell。

Async Thinking

在被 Callback Hell 折磨地苦不堪言的同时,开始有人探索怎样避免 Callback 的困扰。这期间出现了各种各样的解决方案,可谓百花齐放。虽然这些解决方法也有一些不足,但是比起Callback 有了很大的进步,异步代码写起来更加高效,理解起来更加易懂。除此之外,它们的设计思想值得学习。

注意 Callback 和 Callback Hell 的区别,我们不能消除 Callback(JS 异步机制就这样)。我们的目的是消除 Callback Hell,使得异步编程更加高效,异步代码更容易阅读和理解,这个是从人的角度来说。

Async

Async 是一个异步编程工具模块。

waterfall

按顺序运行 tasks 中的异步操作,每个异步操作通过callback将结果传递给下一个异步操作。

waterfall(tasks, callback)

step1、step2、step3 将按照在数组中的顺序被执行。

async.waterfall([function step1(callback) {callback(null, 'one', 'two');},function step2(arg1, arg2, callback) {// arg1 now equals 'one' and arg2 now equals 'two'callback(null, 'three');},function step3(arg1, callback) {// arg1 now equals 'three'callback(null, 'done');}
], function (err, result) {// result now equals 'done'
});

series

按照tasks的顺序执行数组中的异步操作。并在所有的异步操作完成后把结果数组传递给 Callback。

series(tasks, callback)

step1、 step2 执行完成后,把结果 ['one', 'two'] 传递给 Callback。

async.series([function step1(callback) {// do some stuff ...callback(null, 'one');},functionstep2(callback) {// do some more stuff ...callback(null, 'two');}
],
// optional callback
function(err, results) {// results is now equal to ['one', 'two']
});

Eventproxy

EventProxy 是一个基于事件机制的异步编程工具。正如作者所说:EventProxy 仅仅是一个很轻量的工具,但是能够带来一种事件式编程的思维变化。可以说, EventProxy 是一个小而美的代码工具,推荐读一下源码,对 JS 事件的运用巧妙而有趣。

EventProxy的特点:

  • 利用事件机制解耦复杂业务逻辑。
  • 移除被广为诟病的深度callback嵌套问题。
  • 将串行等待变成并行等待,提升多异步协作场景下的执行效率。
  • 友好的Error handling。
  • 无平台依赖,适合前后端,能用于浏览器和Node.js。

过去的,深度嵌套的,串行的异步代码。

const render = function (template, data) {_.template(template, data);
};$.get("template", function (template) {// something$.get("data", function (data) {// something$.get("l10n", function (l10n) {// somethingrender(template, data, l10n);});});
});

现在的,无深度嵌套的,并行的异步代码。

const ep = EventProxy.create("template", "data", "l10n", function (template, data, l10n) {_.template(template, data, l10n);
});$.get("template", function (template) {// somethingep.emit("template", template);
});
$.get("data", function (data) {// somethingep.emit("data", data);
});
$.get("l10n", function (l10n) {// somethingep.emit("l10n", l10n);
});

Bluebird

Promise 概念最早由E语言提出,E语言使用基于事件循环和Promise的并发模型确保永远不会发生死锁。后来JS开发者把Promise引入JS以解决异步编程callback问题,出现了不少优秀的第三方Promise代码库:JQuery的deferred、q模块和Bluebird等。官方则在ES6中加入了实现Promise/A++标准的Promise。

Promise对象可以用于表示一次异步操作的最终状态(完成或失败),以及其返回的值。比传统的解决方案 "回调函数和事件" 更合理和更强大,把异步编程从callback嵌套变成改成链式调用。更多Promise的介绍请看JS Promise。Promise在JS中出现,使得异步编程开始编程走向统一化和标准化。

Bluebird是一个第三方Promise规范实现库,它不仅完全兼容原生Promise对象,且比原生对象功能更强大。虽然ES加入了Promise,但是Bluebird依然有很多出色的功能值得去体验。

new Promise

使用Promise来封装原来使用callback的异步操作,从而实现Promise的风格处理异步代码。

const promise = new Promise(function(resolve, reject) {// 异步操作if (•••) { // 根据异步操作结果判断resolve(value); // success} else {reject(reason); // failure}
});

把原本使用callback处理网络异步请求结果转换成使用then的风格。把单个异步操作封装成一个Promise对象实例,并通过then把多个异步操作改成链式调用关联起来串行处理。

function ajaxGetAsync(url) {return new Promise(function (resolve, reject) {const xhr = new XMLHttpRequest;xhr.addEventListener("error", reject);xhr.addEventListener("load", resolve);xhr.open("GET", url);xhr.send(null);});
}ajaxGetAsync('http://www.xx.com/user/1')
.then(function(user) {return ajaxGetAsync(`http://www.xx.com/user/${user.id}/orders`)
})then(function(orders) {// 请求成功的处理
}).catch(function(err) {// 请求失败的处理	
});

Promise.promisifyAll

把对象中所有的方法全部增加一个promise化的方法。这个方法对于依然使用callback的代码很有帮助,使得我们可以使用Promise的方式去使用这些非Promise风格代码。

const Promise = require('bluebird');
const fs = require('fs');
const path = require('path');Promise.promisifyAll(fs);fs.readFileAsync(path.join(__dirname, 'sample.txt'), 'utf-8').then(data => console.log(data)).catch(err => console.error(err));

Promise.map

把多个异步操作转封装成Promise对象,并发处理异步代码(默认同时处理全部),并提供concurrency参数控制同时并发数量。在实际开发中,经常会遇到有大量请求要并发处理的情况,为了控制并发数,我一般选择使用concurrency参数。这个功能比较实用,但是实现起来也不难,可以自己拓展ES6的Promise中使用计数器的方式就可以实现这个功能。

Promise.map(Iterable<any>|Promise<Iterable<any>> input,function(any item, int index, int length) mapper,[Object {concurrency: int=Infinity} options]
) -> Promise

并发读取三个文件的内容,三个文件读取完成后以数组的形式返回结果。

Promise.map(['1.txt', '2.txt', '3.txt'],name => fs.readFileAsync(path.join(__dirname, name), 'utf-8')
).then(results => console.log(results.join(','))
).catch(console.error);

ES6 Promise

官方在ES6加入了实现Promise/A++标准的Promise,统一了用法,原生提供了Promise。

其实早在社区引入Promise的时候,已经有不少代码库使用了Promise风格,等到了Promise正式加入规范,很多代码库都增加了支持Promise的版本,但是为了兼容旧的代码,也依然保存callback版本,甚至两种同时提供。

Promise虽然比callback更加强大,但是面对复杂的异步编程场景依然显得有些力不从心,代码依然出现难以编写和理解的情况。一大堆then,原来的语义变得很不清楚。

Generator

ES6同时还引入了generator函数,一种新的异步编程解决方案。

Generator也不是完全独立的一种异步编程方案,实际上是和Promise配套使用的。

// 串行执行
function* render () {const template = yield $.get('template');const data = yield $.get('data');const l10n = yield $.get('l10n');_.template(template, data, l10n);
};const gen = render();
gen.next(); // get template
gen.next(); // get data
gen.next(); // get l10n// 并发执行
function* render () {const [template, data, l10n] = yield [$.get('template'), $.get('data'), $.get('l10n')];_.template(template, data, l10n);

Generator automation

Generator和Promise的组合带来了更新更酷的异步编程体验,但是每一次异步操作都要手动调用next()函数,代码重复且容易出错(异步操作多的时候,数next的次数够需要耐心的)。于是TJ写了一个可以自动执行generator函数的模块co。

co(function* render () {const template = yield $.get('template');const data = yield $.get('data');const l10n = yield $.get('l10n');_.template(template, data, l10n);
}).catch(err => console.error(err));

Async function

ES7引入了async函数,统一化、规范化和标准化了异步编程。Async函数使得异步编程更加容易理解,复合人类的阅读习惯。

Async函数本质上就是Generator函数的语法糖。Async函数依然是和Promise组合使用。

async function render () {const template = await $.get('template');const data = await $.get('data');const l10n = await $.get('l10n');_.template(template, data, l10n);
}).catch(err => console.error(err));

参考

  • JavaScript 运行机制详解:再谈Event Loop
  • 关于JavaScript单线程的一些事
  • The JavaScript Event Loop Explained
  • What the heck is the event loop anyway
  • JavaScript Promise迷你书
http://www.lbrq.cn/news/2690983.html

相关文章:

  • 部门网站建设的意义营销策划方案ppt
  • 新闻网站广州网络营销公司
  • 如何做自己的淘宝网站app推广拉新接单平台
  • 蚌埠建设网站公司北京seo公司有哪些
  • 万网没备案怎么做网站短视频怎么赚钱
  • 网站单页制作教程公司网站建设步骤
  • 专业网站建设品牌百度账号注销
  • 照片在线处理工具网站怎么优化搜索
  • 沈阳网红seo网络推广知识
  • 四川省住房和城乡建设局网站网站建设在线建站
  • 如何用虚拟主机做网站seo排名谁教的好
  • 南宁网站关键字优化爱站工具下载
  • 保定市网站设计怎样给自己的网站做优化
  • web网站开发工作经验培训机构排名一览表
  • 慕枫宁波网站建设推广渠道有哪些平台
  • 什么程序做教育网站好营销网站建设流程
  • decorum wordpressseo培训多少钱
  • 如何做网站流量分析报表站长之家ppt素材
  • 南通营销网站制作外贸网站seo推广教程
  • 企业做淘宝客网站有哪些武汉网站设计十年乐云seo
  • 网页设计初学者公司网页设计模板西安百度网站快速优化
  • 建立的网站打开空白seo点击排名软件哪里好
  • 养殖网站模版网络营销顾问工作内容
  • 济南开发网站bt兔子磁力搜索
  • wordpress邮件注册通知搜索引擎优化排名工具
  • 手机网站图片切换jquery可以免费发广告的网站有哪些
  • 关于网站建设的网络诈骗的案例seo博客网址
  • 日本做黄视频网站有哪些开发一个平台需要多少钱
  • wordpress 滑块黄冈网站推广优化找哪家
  • 商店建筑设计优化网站广告优化
  • 开源WAF新标杆:雷池SafeLine用语义分析重构网站安全边界
  • 备战国赛算法讲解——马尔科夫链,2025国赛数学建模B题详细思路模型更新
  • “生成式UI革命”:Tambo AI如何让你的应用“开口说话、动手搭界面” | 全面深剖、案例实践与未来展望
  • 《嵌入式Linux应用编程(四):Linux文件IO系统调用深度解析》
  • 【DL】深层神经网络
  • 负载均衡详解