Promise学习——解决回调地狱问题

Promise

promise 容器概念:

在这里插入图片描述

callback hell(回调地狱):
在这里插入图片描述

文件的读取无法判断执行顺序(文件的执行顺序是依据文件的大小来决定的)(异步api无法保证文件的执行顺序)

var fs = require('fs');fs.readFile('./data/a.text','utf8',function(err,data){if(err){// 1 读取失败直接打印输出读取失败return console.log('读取失败');// 2 抛出异常// 		阻止程序的执行// 		把错误信息打印到控制台throw err;}console.log(data);
});fs.readFile('./data/b.text','utf8',function(err,data){if(err){// 1 读取失败直接打印输出读取失败return console.log('读取失败');// 2 抛出异常// 		阻止程序的执行// 		把错误信息打印到控制台throw err;}console.log(data);
});

通过回调嵌套的方式来保证顺序:

var fs = require('fs');fs.readFile('./data/a.text','utf8',function(err,data){if(err){// 1 读取失败直接打印输出读取失败return console.log('读取失败');// 2 抛出异常// 		阻止程序的执行// 		把错误信息打印到控制台throw err;}console.log(data);fs.readFile('./data/b.text','utf8',function(err,data){if(err){// 1 读取失败直接打印输出读取失败return console.log('读取失败');// 2 抛出异常// 		阻止程序的执行// 		把错误信息打印到控制台throw err;}console.log(data);fs.readFile('./data/a.text','utf8',function(err,data){if(err){// 1 读取失败直接打印输出读取失败return console.log('读取失败');// 2 抛出异常// 		阻止程序的执行// 		把错误信息打印到控制台throw err;}console.log(data);});});
});

为了解决以上编码方式带来的问题(回调地狱嵌套),所以在EcmaScript6新增了一个API:Promise

  • Promise:承诺,保证
  • Promise本身不是异步的,但往往都是内部封装一个异步任务

基本语法:

var fs = require('fs')
// 在EcmaScript 6 中新增了一个API Promise
// Promise 是一个构造函数// 创建 Promise 容器
// 1.给别人一个承诺 I promise you
//		Promise 容器一旦创建,就开始执行里面的代码
var p1 = new Promise(function(resolve, reject) {fs.readFile('./data/a.txt', 'utf-8', function(err, data) {if (err) {// 失败了,承诺容器中的任务失败了// console.log(err)// 把容器的Pending状态变为Rejected// 调用的reject方法实际上就是then方法传递的第二个参数函数functionreject(err)} else {// 承诺容器中的任务成功了// console.log(data)// 把容器的Pending状态变为成功// 也就是说这里调用的resolve方法实际上就是then方法传递的第一个functionresolve(data)}})
})// p1 就是那个承诺
// 当 p1 成功了,然后(then)做指定的操作
// then 方法接收的function就是容器中的resolve函数
p1.then(function(data) {console.log(data)
}, function(err) {console.log('读取文件失败', err)
})

在这里插入图片描述

链式循环:

封装Promise的readFile

var fs = require('fs')function pReadFile(filePath) {return new Promise(function(resolve, reject) {fs.readFile(filePath, 'utf-8', function(err, data) {if (err) {reject(err)} else {resolve(data)}})})
}pReadFile('./data/a.txt').then(function(data) {console.log(data)return pReadFile('./data/b.txt')}).then(function(data) {console.log(data)return pReadFile('./data/c.txt')}).then(function(data) {console.log(data)})

在这里插入图片描述

var fs = require('fs')
// 在EcmaScript 6 中新增了一个API Promise
// Promise 是一个构造函数// 创建 Promise 容器
// 1.给别人一个承诺 I promise you
//		Promise 容器一旦创建,就开始执行里面的代码
var p1 = new Promise(function(resolve, reject) {fs.readFile('./data/a.txt', 'utf-8', function(err, data) {if (err) {// 失败了,承诺容器中的任务失败了// console.log(err)// 把容器的Pending状态变为Rejected// 调用的reject方法实际上就是then方法传递的第二个参数函数functionreject(err)} else {// 承诺容器中的任务成功了// console.log(data)// 把容器的Pending状态变为成功// 也就是说这里调用的resolve方法实际上就是then方法传递的第一个functionresolve(data)}})
})var p2 = new Promise(function(resolve, reject) {fs.readFile('./data/b.txt', 'utf-8', function(err, data) {if (err) {reject(err)} else {resolve(data)}})
})var p3 = new Promise(function(resolve, reject) {fs.readFile('./data/c.txt', 'utf-8', function(err, data) {if (err) {reject(err)} else {resolve(data)}})
})// p1 就是那个承诺
// 当 p1 成功了,然后(then)做指定的操作
// then 方法接收的function就是容器中的resolve函数
p1.then(function(data) {console.log(data)// 当 p1读取成功的时候// 当前函数中 return 的结果就可以在后面的 then中function接收到// 当return 一个 promise 对象的时候,后续的then中的方法的第一个参数会作为p2 的resolvereturn p2
}, function(err) {console.log('读取文件失败', err)
}).then(function(data) {console.log(data)return p3
}).then(function(data) {console.log(data)
})

在这里插入图片描述

需求:分别向两个接口:users和jobs发送请求,获取响应数据,将数据通过art-template 模板渲染到html页面上

第一种:使用自己封装的callback方式

在这里插入图片描述

data.json:

{"users": [{"id": 1,"username": "admin","age": 22,"job": 4},{"id": 2,"username": "admin2","age": 18,"job": 1},{"id": 3,"username": "admin3","age": 18,"job": 1}],"jobs": [{"id": 1,"name": "学生"},{"id": 2,"name": "老师"},{"id": 3,"name": "司机"},{"id": 4,"name": "演员"},{"id": 5,"name": "画家"},{"id": 6,"name": "电竞人"}]
}

这里使用json-server来开启一个服务:
首先,安装 json-server: npm install -g json-server
在这里插入图片描述
然后通过命令:json-server --watch data.json启动服务:
在这里插入图片描述
在这里插入图片描述
由于用到了模板引擎来将数据渲染到页面上,所以需要再安装一个art-template包:
npm i art-template
在这里插入图片描述

<!DOCTYPE html>
<html><head><meta charset="utf-8"><title></title></head><body><form action="#" id="user_form"></form><script type="text/text/template" id="tpl"><label for="">用户名</label><input type="text" value="{{ user.username }}"><label for="">年龄</label><input type="text" value="{{ user.age }}"><label for="">职业</label><select name="" id="">{{ each jobs }}{{ if user.job === $value.id }}<option value="{{ $value.id }}" selected="selected">{{ $value.name }}</option>{{ else }}<option value="{{ $value.id }}">{{ $value.name }}</option>{{ /if }}		{{ /each }}</select>						</script><script src="node_modules/art-template/lib/template-web.js"></script><script>// 用户表// 		其中一个接口获取用户数据//      职业:1// 职业信息表//  	其中一个接口获取所有的职业信息get('http://127.0.0.1:3000/users/1', function(userData) {// data = JSON.parse(data)get('http://127.0.0.1:3000/jobs', function(jobsData) {// console.log(userData, jobsData)var htmlStr = template('tpl', {user: JSON.parse(userData),jobs: JSON.parse(jobsData)})console.log(htmlStr)document.querySelector('#user_form').innerHTML = htmlStr})})function get(url, callback) {var oReq = new XMLHttpRequest()// 当请求加载成功之后要调用指定的函数oReq.onload = function() {// 我现在需要得到这里的 oReq.responseTextcallback(oReq.responseText)}oReq.open("get", url, true)oReq.send()}</script></body>
</html>

在这里插入图片描述

第二种:使用jquery的promise方式

在这里插入图片描述

<!DOCTYPE html>
<html><head><meta charset="utf-8"><title></title></head><body><form action="#" id="user_form"></form><script type="text/text/template" id="tpl"><label for="">用户名</label><input type="text" value="{{ user.username }}"><label for="">年龄</label><input type="text" value="{{ user.age }}"><label for="">职业</label><select name="" id="">{{ each jobs }}{{ if user.job === $value.id }}<option value="{{ $value.id }}" selected="selected">{{ $value.name }}</option>{{ else }}<option value="{{ $value.id }}">{{ $value.name }}</option>{{ /if }}		{{ /each }}</select>						</script><script src="node_modules/jquery/dist/jquery.js"></script><script src="node_modules/art-template/lib/template-web.js"></script><script>// 用户表// 		其中一个接口获取用户数据//      职业:1// 职业信息表//  	其中一个接口获取所有的职业信息/* get('http://127.0.0.1:3000/users/1', function(userData) {// data = JSON.parse(data)get('http://127.0.0.1:3000/jobs', function(jobsData) {// console.log(userData, jobsData)var htmlStr = template('tpl', {user: JSON.parse(userData),jobs: JSON.parse(jobsData)})console.log(htmlStr)document.querySelector('#user_form').innerHTML = htmlStr})}) */var data = {}$.get('http://127.0.0.1:3000/users/1').then(function(userData) {console.log(userData)data.user = userDatareturn $.get('http://127.0.0.1:3000/jobs')}).then(function(jobsData) {console.log(jobsData)data.jobs = jobsDataconsole.log(data)var htmlStr = template('tpl', data)console.log(htmlStr)document.querySelector('#user_form').innerHTML = htmlStr})function get(url, callback) {var oReq = new XMLHttpRequest()// 当请求加载成功之后要调用指定的函数oReq.onload = function() {// 我现在需要得到这里的 oReq.responseTextcallback(oReq.responseText)}oReq.open("get", url, true)oReq.send()}</script></body>
</html>

在这里插入图片描述

3.用promise封装ajax版:

<!DOCTYPE html>
<html><head><meta charset="utf-8"><title></title></head><body><form action="#" id="user_form"></form><script type="text/text/template" id="tpl"><label for="">用户名</label><input type="text" value="{{ user.username }}"><label for="">年龄</label><input type="text" value="{{ user.age }}"><label for="">职业</label><select name="" id="">{{ each jobs }}{{ if user.job === $value.id }}<option value="{{ $value.id }}" selected="selected">{{ $value.name }}</option>{{ else }}<option value="{{ $value.id }}">{{ $value.name }}</option>{{ /if }}		{{ /each }}</select>						</script><script src="node_modules/jquery/dist/jquery.js"></script><script src="node_modules/art-template/lib/template-web.js"></script><script>// 用户表// 		其中一个接口获取用户数据//      职业:1// 职业信息表//  	其中一个接口获取所有的职业信息/* get('http://127.0.0.1:3000/users/1', function(userData) {// data = JSON.parse(data)get('http://127.0.0.1:3000/jobs', function(jobsData) {// console.log(userData, jobsData)var htmlStr = template('tpl', {user: JSON.parse(userData),jobs: JSON.parse(jobsData)})console.log(htmlStr)document.querySelector('#user_form').innerHTML = htmlStr})}) */
/* var data = {}$.get('http://127.0.0.1:3000/users/1').then(function(userData) {console.log(userData)data.user = userDatareturn $.get('http://127.0.0.1:3000/jobs')}).then(function(jobsData) {console.log(jobsData)data.jobs = jobsDataconsole.log(data)var htmlStr = template('tpl', data)console.log(htmlStr)document.querySelector('#user_form').innerHTML = htmlStr}) */var data = {}get('http://127.0.0.1:3000/users/1').then(function(userData) {data.user = userDatareturn $.get('http://127.0.0.1:3000/jobs')}).then(function(jobsData) {data.jobs = jobsDatavar htmlStr = template('tpl', data)document.querySelector('#user_form').innerHTML = htmlStr			}) function get(url) {return new Promise(function(resolve, reject) {var oReq = new XMLHttpRequest()// 当请求加载成功之后要调用指定的函数oReq.onload = function() {// 我现在需要得到这里的 oReq.responseTextresolve(JSON.parse(oReq.responseText))}			oReq.onerror = function (err) {reject(err)}oReq.open("get", url, true)oReq.send()})}/* function get(url, callback) {var oReq = new XMLHttpRequest()// 当请求加载成功之后要调用指定的函数oReq.onload = function() {// 我现在需要得到这里的 oReq.responseTextcallback(oReq.responseText)}oReq.open("get", url, true)oReq.send()} */</script></body>
</html>

在这里插入图片描述

mongoose所有的API都支持Promise:

// 查询所有
User.find().then(function(data){console.log(data)})

注册:

User.findOne({username:'admin'},function(user){if(user){console.log('用户已存在')} else {new User({username:'aaa',password:'123',email:'fffff'}).save(function(){console.log('注册成功');})}
})
User.findOne({username:'admin'
}).then(function(user){if(user){// 用户已经存在不能注册console.log('用户已存在');}else{// 用户不存在可以注册return new User({username:'aaa',password:'123',email:'fffff'}).save();}}).then(funciton(ret){console.log('注册成功');})

Generator

async函数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/470771.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于哈希表的索引堆变形(Hackerrank: QHEAP1)

问题来源 此题来自于Hackerrank中的QHEAP1问题&#xff0c;考查了对堆结构的充分理解。成功完成此题&#xff0c;对最大堆或者最小堆的基本操作实现就没什么太大问题了。 问题简述 实现一个最小堆&#xff0c;对3种类型的输入能给出正确的操作&#xff1a; “1 v” - 表示往…

Node 中的path模块

参考文档&#xff1a;https://nodejs.org/docs/latest-v13.x/api/path.html path模块中的常用API&#xff1a; path.basename&#xff1a;获取路径的文件名&#xff0c;默认包含扩展名path.dirname&#xff1a;获取路径中的目录部分path.extname&#xff1a;获取一个路径中的扩…

利用回溯法解决1-9之间添加+或-或使得运算结果为100的问题

问题描述 编写一个在1&#xff0c;2&#xff0c;…&#xff0c;9&#xff08;顺序不能变&#xff09;数字之间插入或-或什么都不插入&#xff0c;使得计算结果总是100的程序&#xff0c;并输出所有的可能性。例如&#xff1a;1 2 34 – 5 67 – 8 9 100。 问题分析 这时…

Atitit。数据库 安全性 重要敏感数据加密存储解决方案

Atitit。数据库 安全性 重要敏感数据加密存储解决方案 1.1. 加密存储的重要性1 1.2. 使用的加密算法aes1 1.3. 数据加密以后会有一些问题。1 1.3.1. 一个是统计&#xff0c;比如统计资金总额。。就无法直接使用sql的sum等数据库内部聚合函数来处理了。。1 1.3.2. 还有一个就是按…

Node中的fs模块

1.fs.stat检测是文件还是目录 2.fs.mkdir创建目录 3.fs.writeFile创建写入文件 4.fs.appendFile追加文件 5.fs.readFile 读取文件 6.fs.readdir读取目录 7.fs.rename重命名 8.fs.rmdir删除目录 9.fs.unlink 删除文件 fs.stat 检测是文件还是目录 const fs require(fs)fs.stat…

主成分分析(PCA)和基于核函数的主成分分析(KPCA)入门

文章目录1 前言2 PCA的原理2.1 什么是投影2.2 投影后的方差2.3 转化为求特征值的问题2.4 符号的表示3 KPCA的原理4 PCA和KPCA在Python中的使用4.1 PCA的使用4.2 KPCA的使用5 参考文献1 前言 主成分分析是在做特征筛选时的重要手段&#xff0c;这个方法在大部分的书中都只是介绍…

算法分类整理+模板①:矩阵快速幂

一直有一个想法&#xff0c;感觉自己很多基础算法不是很扎实&#xff0c;想要找个机会写一些算法的整理&#xff0c;顺便自己总结一些实用的模板。 最近偶然在训练赛中连续做了2道思维矩阵快速幂的题目&#xff0c;碰巧有时间&#xff0c;就以矩阵快速幂作为这个系列博客的开始…

爬虫小记:利用cookies跳过登陆验证码

前言 在爬取某些网页时&#xff0c;登陆界面时经常遇到的一个坎&#xff0c;而现在大多数的网站在登陆时都会要求用户填写验证码。当然&#xff0c;我们可以设计一套机器学习的算法去破解验证码&#xff0c;然而&#xff0c;验证码的形式多种多样&#xff0c;稍微变一下&#…

IOS的 testflight测试设置

管理员邀请参与者 1、登录开发者账号https://developer.apple.com/account 2、进入后&#xff0c;点击ituns connect 3、点击进入用户和职能 4、在用户栏点击添加按钮 5、输入姓名、邮件 6、勾选职能为“开发人员”&#xff0c;选择所要测试或参与研发的APP 7、不用修改&#x…

Nodejs 中的包、npm 、第三方模块、 package.json 以及 cnpm

一、包与 NPM 包Nodejs 中除了它自己提供的核心模块外&#xff0c;我们可以自定义模块&#xff0c;也可以使用第三方的 模块。Nodejs 中第三方模块由包组成&#xff0c;可以通过包来对一组具有相互依赖关系的模块进行 统一管理。 完全符合 CommonJs 规范的包目录一般包含如下…

神经网络中BP(back propagation)到底在干些什么

前言 想要理解神经网络的工作原理&#xff0c;反向传播(BP)是必须搞懂的东西。BP其实并不难理解&#xff0c;说白了就是用链式法则(chain rule)算算算。本文试图以某个神经网络为例&#xff0c;尽可能直观&#xff0c;详细&#xff0c;明了地说明反向传播的整个过程。 正向传…

TOP 子句

TOP 子句TOP 子句用于规定要返回的记录的数目。对于拥有数千条记录的大型表来说&#xff0c;TOP 子句是非常有用的。注释&#xff1a;并非所有的数据库系统都支持 TOP 子句。SQL Server 的语法&#xff1a;SELECT TOP number|percent column_name(s)FROM table_nameMySQL 和 Or…

Nodejs 新特性 async await 的使用 以及使用 async await 处理异步

1. let 和 var 2. const定义常量 3. 模板字符串 4. 属性简写 5. 方法简写 6. 箭头函数 7. 回调函数 7. Promise 8. async 和 await

leetcode 高薪_LeetCode 第 125 号问题:验证回文串

本文首发于公众号「五分钟学算法」&#xff0c;是图解 LeetCode 系列文章之一。个人网站&#xff1a;https://www.cxyxiaowu.com题目来源于 LeetCode 第 125 号问题&#xff1a;验证回文串。这道题目是 初级程序员 在面试的时候经常遇到的一道算法题&#xff0c;而且面试官喜欢…

从拉格朗日乘子法到SVM

前言 本文主要是讲了如何构建SVM的模型&#xff0c;并利用KKT条件构造其对偶型&#xff0c;从而求解问题&#xff0c;并讲述了SVM的硬间隔&#xff0c;软间隔和核函数三个境界。主要参考了周志华的《机器学习》&#xff0c;并在其中补充了自己的想法。由于内容较多&#xff0c…

nodejs 创建一个静态资源服务器 +路由

0、补充 1、Node.js 创建的第一个应用 1、引入 http 模块 var http require("http"); 2、创建服务器 接下来我们使用 http.createServer() 方法创建服务器&#xff0c;并使用 listen 方法绑定 3000 端口。 函数通过 request, response 参数来接收和响应数据。 co…

python输出字体的大小_Python密码学编程:文件的加密与解密

在之前的章节中&#xff0c;编写的程序只能操作较少的信息&#xff0c;这些信息往往是以字符串的形式直接写在代码中的。但本章中的程序可以对整个文件进行加密和解密&#xff0c;文件的大小可以包括成千上万个字符。本章要点open()方法。读、写文件。write()、close()及read()…

个人工作总结7

时间关系&#xff0c;只能等到编完了程序再做工作总结了&#xff0c;今天是第七天: 一、昨天干了什么&#xff1f; 服务器配置了一大圈&#xff0c;尝试了N1种办法&#xff0c;到最后也没有成功&#xff0c;但好像只差一点点&#xff0c;打算明天上移动应用开发咨询一下老师。 …

电脑k歌软件_金麦客专业k歌app下载|金麦客专业k歌软件 手机安卓版v1.1.5.0 下载...

金麦客专业k歌app能够让用户通过手机直接连接电视&#xff0c;从而在安卓端实现金麦客点歌的目的&#xff0c;平台包含上万高清mv资源&#xff0c;让用户在歌唱时能够更好的代入氛围中&#xff0c;并且还能通过网络直接搜歌&#xff0c;从而在线下载播放&#xff0c;用户在演唱…

python的普通方法、类方法和静态方法

前言 本文主要讲述了python类中的三类常用方法&#xff0c;普通方法、类方法和静态方法。 普通方法会将实例传入方法当中&#xff08;通常用self表示&#xff09;&#xff0c;类方法会将类传入方法当中&#xff08;通常用cls表示&#xff09;&#xff0c;静态方法中传入与类无…