javascript的天生单线程特性,使得异步编程对它异常重要,早期的通常做法是用回调函数来解决。但是随着逻辑的复杂,和javascript在服务端的大显神通,使得我们很容易就陷入“回调陷井”的万丈深渊。对于异步编程问题的解决人们绞尽脑汁。

  • 传统的解决方案

  在ES6之前的传统解决方案有:回调函数,事件监听(事件发布/订阅)。

  • Promise解决方案

  Promise作为一种异步编程的解决方案,最早由社区提出和实现,ES6将其标准化,原生提供了Promise对象。

  Promise其实就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。

  ES6 规定,Promise对象是一个构造函数,用来生成Promise实例。

  下面代码创造了一个Promise实例。

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

  Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolvereject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。

  resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

  Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。

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

  then方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为resolved时调用,第二个回调函数是Promise对象的状态变为rejected时调用。其中,第二个函数是可选的,不一定要提供。这两个函数都接受Promise对象传出的值作为参数。

  下面是一个Promise对象的简单例子。

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

  上面代码中,timeout方法返回一个Promise实例,表示一段时间以后才会发生的结果。过了指定的时间(ms参数)以后,Promise实例的状态变为resolved,就会触发then方法绑定的回调函数。

  Promise 新建后就会立即执行。

  • async函数解决方案

  ES2017 标准引入了 async 函数,使得异步操作变得更加方便。它就是 Generator 函数的语法糖。

  前文有一个 Generator 函数,依次读取两个文件。

const fs = require('fs');

const readFile = function (fileName) {
return new Promise(function (resolve, reject) {
fs.readFile(fileName, function(error, data) {
if (error) return reject(error);
resolve(data);
});
});
}; const gen = function* () {
const f1 = yield readFile('/etc/fstab');
const f2 = yield readFile('/etc/shells');
console.log(f1.toString());
console.log(f2.toString());
};

写成async函数,就是下面这样。

const asyncReadFile = async function () {
const f1 = await readFile('/etc/fstab');
const f2 = await readFile('/etc/shells');
console.log(f1.toString());
console.log(f2.toString());
};

JavaScript异步编程解决方案探究的更多相关文章

  1. Func-Chain.js 另一种思路的javascript异步编程解决方案

    本文转载自:https://www.ctolib.com/panruiplay-func-chain.html Func-Chain.js 另一种思路的javascript异步编程,用于解决老式的回调 ...

  2. JavaScript异步编程的主要解决方案—对不起,我和你不在同一个频率上

    众所周知(这也忒夸张了吧?),Javascript通过事件驱动机制,在单线程模型下,以异步的形式来实现非阻塞的IO操作.这种模式使得JavaScript在处理事务时非常高效,但这带来了很多问题,比如异 ...

  3. javascript异步编程的前世今生,从onclick到await/async

    javascript与异步编程 为了避免资源管理等复杂性的问题, javascript被设计为单线程的语言,即使有了html5 worker,也不能直接访问dom. javascript 设计之初是为 ...

  4. 5分种让你了解javascript异步编程的前世今生,从onclick到await/async

      javascript与异步编程 为了避免资源管理等复杂性的问题,javascript被设计为单线程的语言,即使有了html5 worker,也不能直接访问dom. javascript 设计之初是 ...

  5. 深入解析Javascript异步编程

    这里深入探讨下Javascript的异步编程技术.(P.S. 本文较长,请准备好瓜子可乐 :D) 一. Javascript异步编程简介 至少在语言级别上,Javascript是单线程的,因此异步编程 ...

  6. JavaScript 异步编程的前世今生(上)

    前言 提到 JavaScript 异步编程,很多小伙伴都很迷茫,本人花费大约一周的业余时间来对 JS 异步做一个完整的总结,和各位同学共勉共进步! 目录 part1 基础部分 什么是异步 part2 ...

  7. 探索Javascript异步编程

    异步编程带来的问题在客户端Javascript中并不明显,但随着服务器端Javascript越来越广的被使用,大量的异步IO操作使得该问题变得明显.许多不同的方法都可以解决这个问题,本文讨论了一些方法 ...

  8. javascript异步编程方案汇总剖析

    code[class*="language-"] { padding: .1em; border-radius: .3em; white-space: normal; backgr ...

  9. javascript异步编程,promise概念

    javascript 异步编程 概述 采用单线程模式工作的原因: 避免多线dom操作同步问题,javascript的执行环境中负责执行代码的线程只有一个 内容概要 同步模式和异步模式 事件循环和消息队 ...

随机推荐

  1. Gym 100512B Betting Fast (题意+概率)

    题意:你开始有 s 元钱,然后你要在 t 场内赚到 n 元,每次赢的概率是 p,并且要越快越好. 析:当时没注意这个条件,要越快越好,然后写概率dp,怎么看也不像是对.其实是每次赌 min(s, n- ...

  2. E20170521-ts

    redirect vt. 使改寄,更改(信件等)姓名地址; 改变方向,改变线路; 重新寄送; teletype   n. 电传打字机,电报交换机,打字电报通讯; descriptor n. 描述符; ...

  3. form表单提交的几种方法

    form表单提交的几种方法 <form id="myform" name="myform" method="post" onsubmi ...

  4. bzoj 2876: [Noi2012]骑行川藏【拉格朗日乘数法+二分】

    详见: http://blog.csdn.net/popoqqq/article/details/42366599 http://blog.csdn.net/whzzt/article/details ...

  5. 使用vmware12安装Ubuntu 遇到的两个问题和解决

    1.need the x86-64 cpu,but only detected the xxx cpu. 这是因为bios中的virtual function 是 disabled,改为enabled ...

  6. .NET Core 跨平台物联网开发:上报属性(三)

    系列教程目录 (一) 连接阿里云IOT (二) 设置委托事件 (三) 上报属性 (四)  SDK文档 属性.方法.委托.类 http://pan.whuanle.cn/index.php?dir=up ...

  7. Kruskal HDOJ 4313 Matrix

    题目传送门 题意:如何花最小的代价使得一棵树划分开且不含同类节点 分析:当一条边连接的左右集合同类点小于等于1,那么不用删除,将两个集合合并,要求最小代价,那么贪心思想将权值降序排序,删除后剩下的就是 ...

  8. 题解报告:CODE[VS] 1082 线段树练习3(区间修改+区间查询)

    题目描述 Description 给你N个数,有两种操作: 1:给区间[a,b]的所有数增加X 2:询问区间[a,b]的数的和. 输入描述 Input Description 第一行一个正整数n,接下 ...

  9. 225 Implement Stack using Queues 队列实现栈

    Implement the following operations of a stack using queues. push(x) -- Push element x onto stack.pop ...

  10. Node.js(二)常用的系统模块

    http模块 第一章已经介绍了 node.js 的模块都可以传一个回调函数  回调函数支持两个参数  error , data let fs = require('fs'); fs.readFile( ...