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

  • 传统的解决方案

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

  • Promise解决方案

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

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

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

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

  1. const promise = new Promise(function(resolve, reject) {
  2. // ... some code
  3.  
  4. if (/* 异步操作成功 */){
  5. resolve(value);
  6. } else {
  7. reject(error);
  8. }
  9. });

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

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

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

  1. promise.then(function(value) {
  2. // success
  3. }, function(error) {
  4. // failure
  5. });

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

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

  1. function timeout(ms) {
  2. return new Promise((resolve, reject) => {
  3. setTimeout(resolve, ms, 'done');
  4. });
  5. }
  6.  
  7. timeout(100).then((value) => {
  8. console.log(value);
  9. });

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

  Promise 新建后就会立即执行。

  • async函数解决方案

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

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

  1. const fs = require('fs');
  2.  
  3. const readFile = function (fileName) {
  4. return new Promise(function (resolve, reject) {
  5. fs.readFile(fileName, function(error, data) {
  6. if (error) return reject(error);
  7. resolve(data);
  8. });
  9. });
  10. };
  11.  
  12. const gen = function* () {
  13. const f1 = yield readFile('/etc/fstab');
  14. const f2 = yield readFile('/etc/shells');
  15. console.log(f1.toString());
  16. console.log(f2.toString());
  17. };

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

  1. const asyncReadFile = async function () {
  2. const f1 = await readFile('/etc/fstab');
  3. const f2 = await readFile('/etc/shells');
  4. console.log(f1.toString());
  5. console.log(f2.toString());
  6. };

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. 小程序-文章:微信小程序常见的UI框架/组件库总结

    ylbtech-小程序-文章:微信小程序常见的UI框架/组件库总结 1.返回顶部 1. 想要开发出一套高质量的小程序,运用框架,组件库是省时省力省心必不可少一部分,随着小程序日渐火爆,各种不同类型的小 ...

  2. HDU3949:XOR(高斯消元)(线性基)

    传送门 题意 给出n个数,任意个数任意数异或构成一个集合,询问第k大个数 分析 这题需要用到线性基,下面是一些资料 1.高斯消元&线性基&Matirx_Tree定理 笔记 2.关于线性 ...

  3. 【插件开发】—— 6 SWT 复杂控件使用以及布局

    前文回顾: 1 插件学习篇 2 简单的建立插件工程以及模型文件分析 3 利用扩展点,开发透视图 4 SWT编程须知 5 SWT简单控件的使用与布局搭配 前几篇讲到了简单控件的使用,复杂控件使用原则上与 ...

  4. JSON WEB TOKEN 从原理到实战

    阅读本文大概需要 4.2 分钟. 作者:王廷骏原文:https://juejin.im/post/5ce272c1e51d45109b01b0f8 1. JSON WEB TOKEN 1.1 什么是J ...

  5. 【SpringCloud构建微服务系列】微服务网关Zuul

    一.为什么要用微服务网关 在微服务架构中,一般不同的微服务有不同的网络地址,而外部客户端(如手机APP)可能需要调用多个接口才能完成一次业务需求.例如一个电影购票的手机APP,可能会调用多个微服务的接 ...

  6. 贪心+stack Codeforces Beta Round #5 C. Longest Regular Bracket Sequence

    题目传送门 /* 题意:求最长括号匹配的长度和它的个数 贪心+stack:用栈存放最近的左括号的位置,若是有右括号匹配,则记录它们的长度,更新最大值,可以在O (n)解决 详细解释:http://bl ...

  7. 使用Maven将dubbox安装进资源仓库

    dubbox网址:https://github.com/dangdangdotcom/dubbox dobbox版本:https://github.com/dangdangdotcom/dubbox/ ...

  8. 随机L系统分形树 分类: 计算机图形学 2014-06-01 23:27 376人阅读 评论(0) 收藏

    下面代码需要插入到MFC项目中运行,实现了计算机图形学中的L系统分形树. class Node { public: int x,y; double direction; Node(){} }; CSt ...

  9. Drawable(7)让一个没有pressed状态的控件使用StateList,显示pressed图片。

    TextView没有按下状态,Button有. 如图1,内容1在一个TextView上,默认它并没有按下状态. 如何让TextView有呢. 在xml中加入属性: android:clickable= ...

  10. Optimizing Downloads for Efficient Network Access

    Optimizing Downloads for Efficient Network Access Previous  Next 1.This lesson teaches you to Unders ...