为什么出现Promise

在javascript开发过程中,代码是单线程执行的,同步操作,彼此之间不会等待,这可以说是它的优势,但是也有它的弊端,如一些网络操作,浏览器事件,文件等操作等,都必须异步执行,针对这些情况,起初的操作都是使用回调函数实现。

实现方式如下(伪代码):

function One(callback) {
if (success) {
callback(err, result);
} else {
callback(err, null);
}
} One(function (err, result) {
//执行完One函数内的内容,成功的结果回调回来向下执行
})

上述代码只是一层级回调,如果代码复杂后,会出现多层级的回调,代码可读性也会很差,那有没有一种方式,不用考虑里面的内容,直接根据结果成功还是失败执行下面的代码呢?有的,Promise(承诺),在ES6中对Promise进行了同意的规范。

Promise的含义

Promise原理与讲解

原理
  1. Promise的三种状态

注意Promise在某一时刻只能处于一种状态

  1. Promise的状态改变

Promise的状态改变,状态只能由pending转换为rejected或者rejected,一旦状态改变完成后将无法改变(不可逆性)

用代码讲原理
  1. 创建一个Promise

创建Promise需要用到Promise的构造函数来实现,代码如下:


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

代码分析:

  1. 异步结果传递出去后,then来接
    Promise对象将结果传递出来后,使用then方法来获取异步操作的值:代码如下:


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

代码分析:


promise.then(function (data){
//success
})
.catch(function(error){
//error
})
  1. then的返回值又是怎样呢?先看一段调用两次then的代码:


//之前创建promise操作后
promise.then(function(value){
conlose.log(value); //有值
}.then(function(value)
{
conlose.log(value); //未定义
});

代码分析:

几个常用api

转换的对象是一个常量或者不具备状态的语句,转换后的对象自动处于resolve状态。转换的后的结果和原来一样


var promise =Promise.resolve("hello world");
promise.then(function(result){
console.log(result); //输出结果 hello world
})

转换的对象如果直接是一个异步方法,不可以这么使用。

代码如下


promise.all(
//一系列promise操作
).then(function(results){ }).catch(function(error){ });

代码分析:

Promise在开发中的应用

项目开发中promise的应用代码:


Promise.all([
self.count({phoneNumber: mobile, createdOn: {$gt: hour}}),
self.count({ip: ip, createdOn: {$gt: hour}})
]).then(function (results) {
if (results[0] >= 5) {
return callback({code: -1, message: '短信发送频率过快,每手机号1小时内只能发送5次'});
}
if (results[1] >= 5) {
return callback({code: -1, message: '短信发送频率过快,每IP1小时内只能发送5次'});
}
let code = {
phoneNumber: mobile,
code: tool.makeRandomStr(4, 1).toLowerCase(),
createdOn: new Date(),
expiredOn: new Date(new Date().getTime() + (20 * 60 * 1000)), //20分钟失效
ip: ip,
isUsed: false
};
self.create(code, function (err, newCode) {
if (newCode) {
sms.sendSMS(mobile, newCode.code, 'ali', function (err, body) {
console.log(body);
if (err)
console.log("短信验证码发送失败:", err);
});
callback({code: 0, message: "验证码已经发送"});
} else {
callback({code: -1, message: "验证码发送失败,请重试"});
}
})
})

项目开发过程中使用promise.all的代码,当时是为了实现短信验证码发送前的校验功能。all中的两个promise,第一个是统计时间内该手机号发送验证码数量;第二个是统计时间内该ip发送验证码的数量。

Promise使用过程中注意事项(坑)

注意事项在上面原理讲解过程中,基本都提到过,只是重要的事情多说两遍。

Promise的反思

Promise的讲解就到这里,但是大家在开发过程中,会发现有些时候多次操作异步会出现很多层级的调用,也就是


promise.then(...)	

.then(...)	

.then(...)

这种情况,代码虽然看起来会比callback的回调简介和规范了很多,但是还是感觉一些复杂,有没有更好的解决办法呢?请看下一篇博客

回调的终极使用--async和await的讲解

▼原创系列推荐▼1.JavaScript 重温系列(22篇全)
2.ECMAScript 重温系列(10篇全)
3.JavaScript设计模式 重温系列(9篇全)
4.正则 / 框架 / 算法等 重温系列(16篇全)

你点的每个赞,我都认真当成了喜欢

【JS】302- 回调地狱解决方案之Promise的更多相关文章

  1. 避免Node.js中回调地狱

    为了解决这个阻塞问题,JavaScript严重依赖于回调,这是在长时间运行的进程(IO,定时器等)完成后运行的函数,因此允许代码执行经过长时间运行的任务. downloadFile('example. ...

  2. js异步回调Async/Await与Promise区别 新学习使用Async/Await

    Promise,我们了解到promise是ES6为解决异步回调而生,避免出现这种回调地狱,那么为何又需要Async/Await呢?你是不是和我一样对Async/Await感兴趣以及想知道如何使用,下面 ...

  3. 回调地狱以及用promise怎么解决回调地狱

    哈哈哈,我又又又回来了,不好意思,最近枸杞喝的比较到位,精力比较旺盛. 现在我们来聊一聊啥是回调地狱,注意是回调地狱啊   不是RB人民最爱拍的那啥地狱啊,来吧,上车吧少年,这是去幼儿园的车 都让开, ...

  4. javascript回调地狱真的只能Promise来解决吗?js回调地狱,Promise。

    javascript的灵活在于函数可以当作函数的参数来传递,以及它的异步回调思想.但是这就带了一个很严重的问题,那就是回调次数过多,会影响代码结构,多层嵌套影响代码的可阅读性,也不便于书写. 举个例子 ...

  5. js中的回调函数 和promise解决异步操作中的回调地狱问题。

    回调函数 : 函数作为参数传递到另外一个函数中.简单数据类型和引入数据类型中的数组和对象作为参数传递大家肯定都不陌生,其实引用数据类型中的函数也是可以的. 事实上大家见到的很多,用到的也很多,比如jQ ...

  6. js动画实现&&回调地狱&&promise

    1. js实现动画 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

  7. js中promise解决callback回调地狱以及使用async+await异步处理的方法

    1.callback回调地狱 function ajax(fn) { setTimeout(()=> { console.log('你好') fn() }, 1000) } ajax(() =& ...

  8. 微信小程序:用 Promise 解决方案代替回调地狱。 修复 this._invokeMethod is not a function 的问题

    /** * 将回调地狱转换为 Promise 形式 * https://blog.csdn.net/SEAYEHIN/article/details/88663740 * raw: wx.downlo ...

  9. Ajax请求回调地狱及解决方案(promise、async和await)

    谈及回调地狱发生得情况和解决办法,就必须追溯到原生ajax请求. 先列出服务器提供的数据接口: // 服务器端接口 app.get('/data1', (req, res) => { res.s ...

随机推荐

  1. F#周报2019年第47期

    新闻 相遇WebWindow,.NET Core上的跨平台webview类库 使用Bolero在WebAssembly中运行F# 用于你团队代码库的AI辅助IntelliSense Jupyter N ...

  2. sql注入基本原理

    SQL注入基本原理 WEB技术发展日新月异,但是徒手拼SQL的传统手艺还是受相当多的开发者亲睐.毕竟相比于再去学习一套复杂的ORM规则,手拼更说方便,直观.通常自己拼SQL的人,应该是有听说过SQL注 ...

  3. windows 10 上使用pybind11进行C++和Python代码相互调用 | Interfacing C++ and Python with pybind11 on windows 10

    本文首发于个人博客https://kezunlin.me/post/8b9c051d/,欢迎阅读! Interfacing C++ and Python with pybind11 on window ...

  4. 从零开始入门 | Kubernetes 中的服务发现与负载均衡

    作者 | 阿里巴巴技术专家  溪恒 一.需求来源 为什么需要服务发现 在 K8s 集群里面会通过 pod 去部署应用,与传统的应用部署不同,传统应用部署在给定的机器上面去部署,我们知道怎么去调用别的机 ...

  5. Spring Boot 2.X(十八):集成 Spring Security-登录认证和权限控制

    前言 在企业项目开发中,对系统的安全和权限控制往往是必需的,常见的安全框架有 Spring Security.Apache Shiro 等.本文主要简单介绍一下 Spring Security,再通过 ...

  6. 学习完vue指令 做的一个学生信息录入系统

    一.demo实现原理 输入完个人信息后  点击创建用户  数据就会显示在下面的表格中 用到了vue中的数据双向绑定 v-model v-for 还要js正则 数组的unshift splice 等方法 ...

  7. 16 Zabbix4.4.1系统告警“Zabbix agent is not available (for 3m)“

    点击返回:自学Zabbix之路 点击返回:自学Zabbix4.0之路 点击返回:自学zabbix集锦 Zabbix4.4.1系统告警“Zabbix agent is not available (fo ...

  8. python3 之 内置函数Zip

    python3 内置函数zip 一.简介: 该函数用于将多个可迭代对象作为参数,依次将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的对象.二.实例1: name = ['张三','李四', ...

  9. 2019-11-6:ubuntu安装配置JAVA环境

    1,下载JAVA,官方java 18下载网站:https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-21331 ...

  10. win10 下安装zookeeper+Kafka 的详细步骤(2)

    Win10 下要使用Kafka需要经过以下三个步骤: 1.安装JDK(需要安装依赖java JDK) 2.安装zookeeper(资源协调,分配管理) 3.使用Kafka开发 ============ ...