Promise 是 “14nodejs(7天)” 第五天的课程,但是 Promise 并不属于 Node.js 的内容,而是 ECMScript6 新增的 api
回调地域 既一个异步请求需要另一个异步请求结果
$.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 为一个容器,它包含三个状态,分别为 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 信息
})
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》
JavaScript 用“共享一切”的方法加载代码,这是该语言中最容易出错且最容易让人感到困惑的地方。其他语言使用诸如包这样的概念来定义代码作用域,但在 ECMAScript 6 以前,在应用程序的每一个 JavaScript 中定义的一切都共享一个全局作用域
ECMAScript是一种由Ecma国际(前身为欧洲计算机制造商协会)通过ECMA-262标准化的脚本程序设计语言,一种可以在宿主环境中执行计算并能操作可计算对象的基于对象的程序设计语言。这种语言在万维网上应用广泛,它往往被称为JavaScript或JScript
函数声明 与 函数表达式 是有区别的。执行代码时,解析器会率先读取函数声明,并使其在执行任何代码之前可用(可以访问);至于函数表达式,则必须等到解析器执行到它所在的代码行,才会真正被解释执行。
ECMAScript 2020 是我们最喜欢的编程语言的第 11 版,其中包含一些新功能。有些是小特性,但有些将会有可能永远改变我们编写 JavaScript 的方式。
ECMAScript 2020 是 ECMAScript 语言规范的第11版。自1997年出版第一版以来,ECMAScript 已发展成为世界上使用最广泛的通用编程语言之一。
ECMAScript 语言规范每年都会进行一次更新,而备受期待的 ECMAScript 2024 将于 2024 年 6 月正式亮相。目前,ECMAScript 2024 的候选版本已经发布,为我们带来了一系列实用的新功能。
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!