Callback Hell和ECMAScript6 Promise小白知识_Promise使用教程

Promise 是 “14nodejs(7天)” 第五天的课程,但是 Promise 并不属于 Node.js 的内容,而是 ECMScript6 新增的 API回调地域(Callback Hell)回调地域 既一个异步请求需要另一个异步请求结果$.ajax({url, success: function () { … }})
$.ajax({url,

Callback Hell和ECMAScript6 Promise小白知识

Promise 是 “14nodejs(7天)” 第五天的课程,但是 Promise 并不属于 Node.js 的内容,而是 ECMScript6 新增的 API

Callback Hell和ECMAScript6 Promise小白知识_Promise使用教程

回调地域(Callback Hell)

回调地域 既一个异步请求需要另一个异步请求结果

$.ajax({url, success: function () { ... }})
$.ajax({url, success: function () { ... }})
$.ajax({url, success: function () { ... }})
$.ajax({url, success: function () { ... }})

由于 Javascript 是单线程的,所以这里执行顺序是 ajax1 -> ajax2 -> ajax3 -> ajax4

但是又由于这四个是异步操作,所以这种多线程操作会导致执行顺序不固定

为了保障异步函数的执行顺序,可以通过异步套异步的方式解决

$.ajax({url, success: function () {
    $.ajax({url, success: function () {
		$.ajax({url, success: function () {
			$.ajax({url, success: function () { ... }})
    	}})
    }}) 
}})

以上这种写法就是所谓的回调地域,非常的不利于维护

为了解决这一情况,ECMAScript6 新增了 Promise API

Promise(承诺)

可以理解 Promise 为一个容器,它包含三个状态,分别为 Pending(正在执行) 、Resolved(已解决) 、Rejected(未解决)

Promise 本身并不是异步的,但其包裹的内容函数为异步函数

// 通过 new Promise 创建 Promise 容器
// 实例化 Promise
var p1 = new Promise (function (resolve, reject) { // Promise 容器(它本身不是异步方法)
    $.ajax({ // $.ajax 异步方法
        url,
        success: function () {
            resolve(data) // 改变容器状态为成功
        },
        error: function () {
        	reject(err) // 改变容器状态为失败
        }
    })
})

容器接收两个形参:

resolve 改变容器状态为成功reject 改变容器状态为失败

通过 .then() 决定实例成功后的指定操作

p1.then(function (data) {
    console.log(data) // 接收 p1 实例成功状态 resolve 抛出的数据 data 
    return p2 // 返回第二个 Promise 容器
}, function (err) {
    console.log(err) // 接收 p1 实例失败状态 reject 抛出的数据 data
})

.then 包含两个函数参数:

第一个函数的参数接收 Promise 容器中的 resolve 抛出的成功内容第二个函数的参数接收 Promise 容器中的 reject 抛出的失败信息

在 .then 的第一个函数中可以返回数据,此数据可以提供给后续 .then 接收使用

如果没有 return 返回值,则后续接收到 undefined如果 return 返回一个 Promise 对象时,后续 .then 第一个函数接收该 Promise 对象的 resolve 状态,第二个函数接收该 Promise 对象的 reject 状态

到此,通过以上的介绍可以 优化回调地域(Callback Hell)

// 通过 new Promise 创建 Promise 容器
// 实例化 Promise
var p1 = new Promise (function (resolve, reject) { // Promise 容器(它本身不是异步方法)
    $.ajax({ // $.ajax 异步方法
        url,
        success: function () {
            resolve(data) // 改变容器状态为成功
        },
        error: function () {
        	reject(err) // 改变容器状态为失败
        }
    })
})
var p2 = new Promise (function (resolve, reject) { ... })
var p3 = new Promise (function (resolve, reject) { ... })
var p4 = new Promise (function (resolve, reject) { ... })
// 操作实例
p1
    .then(function (data) {
        console.log(data) // 打印 p1 的 data 内容
        return p2 // 向下传递实例 p2
    }, function (err) {
        console.log(err) // 打印 p1 的 err 信息
    })
    .then(function (data) {
        console.log(data) // 打印 p2 的 data 内容
        return p3 // 向下传递实例 p3
    }, function (err) {
        console.log(err) // 打印 p2 的 err 信息
    })
    .then(function (data) {
        console.log(data) // 打印 p3 的 data 内容
        return p4 // 向下传递实例 p4
    }, function (err) {
        console.log(err) // 打印 p3 的 err 信息
    })
    .then(function (data) {
        console.log(data) // 打印 p4 的 data 内容
    }, function (err) {
        console.log(err) // 打印 p4 的 err 信息
    })

通过判断是否有 then 方法判断其是否是 Promise 对象

var p1 = new Promise (function (resolve, reject) { ... }
function p2 () { ... }
// 替换下段代码中的 fn 即可查看 P1、P2 是否是 Promise 对象
if (!!fn && typeof fn.then === 'function') {
    console.log('是Promise')
} else {
    console.log('不是Promise')
}

文章已同步我的个人博客:《Callback Hell和ECMAScript6 Promise》

海计划公众号
(0)
上一篇 2020/03/20 23:49
下一篇 2020/03/20 23:49

您可能感兴趣的内容

  • 失眠几十年太痛苦了怎么办?什么药效果最好,怎么样才可以调理好,需要多久可以治疗好小白攻略_推广入门百科

    我有二三十年的失眠症,到晩上就很兴奋,整夜失眠,特别痛苦,找了N个偏方,各种药物效果都让人失望,以前天天靠阿普唑仑等药物强迫入睡,入睡非常困难,睡眠质量极差!每天烦心事还很多,情绪也尤为烦躁,经常动不动就发火,肝胆都不是太好,经常全身发麻。苦于找不到调理好失眠的方法,一直忍着。有时候自己就在想,为什么别人都好好的,就自己可以失眠这么长的时间,怎么就是治疗不好

    2020/03/30
  • 互房客携手正达打造南疆人居标杆 即将盛大启幕使用攻略_活动新手入门

    中式庭院 | 阔景大宅阿克苏正达-天山熙湖—期【国仕山】采用新中式风格,汲取中式压顶、通花格、直棂窗等中国传统建筑元素,将中式的经典元素提炼并加以丰富,采用线条设计突出建筑的现代感,各元素相互融合、相辅相成,从而产生独具一格的新中式建筑风格。在充分保证建筑美感的同时,让更多的绿色、水系和景观成为现实。未来居住于此,无论游走在客厅还是主卧,园林如一缕画

    2020/03/24
  • eruda使用教程_一个专为手机网页前端设计的调试面板

    eruda使用教程 官方网址:https://eruda.liriliri.io/ GitHub:https://github.com/liriliri/eruda 简介描述:一个…

    2020/03/06
  • 如何将JSON反序列化为JavaScript对象?使用说明_对象基础知识教程

    JSON(JavaScript Object Notation)用于与Web服务器或RESTFull API交换数据,从Web服务器接收的数据始终是字符串。为了使用这些数据,您需要使用JSON.parse()解析数据,它将返回一个JavaScript对象或对象数组。JSON.parse()方法用于解析以JSON格式编写并返回JavaScript对象的JSON

    2020/03/20
  • node为什么不支持import?指南攻略_import基础入门

    nodejs采用的是CommonJS的模块化规范,使用require引入模块;而import是ES6的模块化规范关键字。想要使用import,必须引入babel转义支持,通过babel进行编译,使其变成node的模块化代码。node编程中最重要的思想之一就是模块,而正是这个思想,让JavaScript的大规模工程成为可能。模块化编程在js界流行,也是基于此,

    2020/03/24
  • mo.js入门基础_强大的JavaScript动画图形,一个svg图形库

    mo.js新手入门 官方网址:http://mojs.io/ GitHub:https://github.com/legomushroom/mojs 简介描述:强大的JavaScr…

    2020/03/06
  • 使用 webpack 插件自动生成 vue 路由文件入门教程_路由小白攻略

    一款自动生成 vue 路由文件的 webpack 插件 vue-route-webpack-plugin 在项目中试点成功了,现在在项目中已经不需要再维护路由配置文件了,由插件自动生成,节省了大家维护路由的时间。从长远来看,使用插件自动生成路由是具有一定好处的。当项目中的路由配置非常多的时候,为了区分业务,你可能需要分成许多个文件来存放这些路由文件,这样就不

    2020/03/29
  • 程序员自我欺骗的 9 个谎言基础教程_谎言使用攻略

    “我们对计算机的自信可能使我们犯错误,因为我们希望将现实世界都转化为代码。”程序员有充分的理由感到自豪,因为其他人是无权进入 数据库 并更改的。世界越是依赖计算机定义,程序员的能力就越强。实际上,没有什么代码是完美的代码,计算机也会经常犯错误。当然,许多问题源于我们的程序员所做的假设,这些假设虽然在某些时候是正确的,但在根本上是不正确的。正如马克·吐温(Ma

    2020/03/22
  • popper.js基础教程一个扩展性较好的 tooltips 提示类 JS 插件

    popper.js指南教程 官方网址:https://popper.js.org GitHub:https://github.com/FezVrasta/popper.js 简介描…

    2020/03/06
  • Js中的 NaN小白帮助_NaN菜鸟教程网

    JavaScript 中的数字类型包含整数和浮点数:const integer = 4;
    const float = 1.5;typeof integer; // => ‘number’
    typeof float; // => ‘number’另外还有 2 个特殊的数字值:Infinity(比其他任何数字都大的数字)和 NaN(表示“Not A Numb

    2020/03/20
  • 12 个评估 JS 库你需要关心的事菜鸟教程网_库小白知识

    1 引言作者给出了从 12 个角度全面分析 JS 库的可用性,分别是:特性。稳定性。性能。包生态。社区。学习曲线。文档。工具。发展历史。团队。兼容性。趋势。下面总结一下作者的观点。2 概述 & 精读特性当你调研一个 JS 库,功能当然是最重要的,就好比 React 的用于开发 UI 界面非常方便,这是流行起来的一部分因素。但同时 React 解决的问题很聚焦

    2020/04/03
  • 移动端开发必须知道的小技巧菜鸟教程_技巧菜鸟教程网

    最近在公司写一个混合 app 项目,页面基本全部都是用 H5 完成,嵌入到原生 webview 下。发现一个问题,在 iPhone 6 下 苹果手机的状态栏会挡住页面,导致页面下移,样式错乱,最后网上查找了些解决办法,加了一条 meta 标签解决了问题。今天特来总结下常用的移动端开发需要注意的meta标签及一些小技巧。viewport<meta name="

    2020/03/26
  • TypeScript 用 Webpack/ts-node 运行的配置记录使用指南_配置入门指南

    公司项目代码是用 TypeScript 写的, 中间遇到有些代码不要放到 Node 里面去跑,具体场景一些路由配置, 比较大的一块 JSON 数据定义在 TypeScript 里,我另外有增加脚本, 基于这些 JSON 数据用来生成切换路由的函数,这就需要运行 TypeScript 了, 而且可能包含一些额外的业务代码。首先 Node 运行 TypeScri

    2020/03/26
  • 大龄前端如何准备面试?基础指南_面试小白知识

    前言今年毋庸置疑是找工作的寒冬,今年出来找工作的每一个同学 都是值得尊敬的。 在寒冬季找工作,虽然略难,但是反过来看也会逼迫我们成为更加优秀的自己。但是不管是旺季还是寒冬,有一些优秀的同学找工作还是挺顺利的。 所以说还是得提高我们自己的硬实力。今年前端很明显一个变化就是前端面试里除了基础知识 也添加了很多手写算法以及前端递归小程序。 下面从若干个方向谈一谈需

    2020/03/23
  • Vue最佳实践基础指南_vue指南攻略

    Vue 最佳实践,是参考 Vue 官方风格指南并根据过去 Vue 实际项目开发中的经验总结的一套规范建议。本项目的目的是希望每个 Vue 开发者都能尽快熟悉并上手项目代码,志在帮助 Vue 新手开发者及时避免一些不规范的设计和由此而引发的问题。本建议如有不妥之处,敬请指正!非常欢迎有志同道合的开发者贡献更多、更好的建议。小弟先开个头,大佬们一起可好!项目地址

    2020/03/24
  • 缺这项能力,做不了技术管理工作菜鸟教程下载_管理基础入门

    摘要: 项目管理能力修炼的6个阶,我们在“程序员加薪升职之成长金字塔”中介绍了职场成长金字塔:大部分开发者工作三五年后,都能掌握所在岗位必须的知识、经验和技能,然而很多人接下来就陷入困境,左冲右突,无法加薪升职,一直停在第1层,三年五年过去了,八年十年过去了,可能都还停在1层的位置。对开发者来讲,第1层对应的就是具体的软件开发角色,卡在这层无法晋升,是指没办

    2020/03/31