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;获取一个路径中的扩…

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;稍微变一下&#…

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

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

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

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

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()…

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

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

Nodejs ejs模板引擎

官方网站&#xff1a;https://www.npmjs.com/package/ejs 我们学的 EJS 是后台模板&#xff0c;可以把我们数据库和文件读取的数据显示到 Html 页面上面。它 是一个第三方模块&#xff0c;需要通过 npm 安装 npm install ejs –save 或者 cnpm install ejs --saveNodejs 中使用…

linux can总线接收数据串口打包上传_关于串口,你需要知道这些!!

嵌入式设备在电路中交换信息的时候必须通过共享一个通用的协议。现在嵌入式系统中已经定义了数百种通信协议来实现数据交换&#xff0c;一般来说可以将其分为两类&#xff1a;并行或串行。并行传输数据是指同时传输多个数据位&#xff0c;它们通常需要数据线和时钟线配合工作&a…

div里嵌套了img底部会有白块问题和图片一像素问题解决

div里嵌套了img底部会有白块 因为img默认是按基线(baseline)对齐的。对比一下图片和右边的p, q, y等字母&#xff0c;你会发现这三个字母的“小尾巴”和图片下方的空白一样高。下面这张图中的黑线就是那条基线。 解决方案&#xff1a;一&#xff1a;vertical-align: bottom&…

Nodejs 中的Get、Post

Get、Post 超文本传输协议&#xff08;HTTP&#xff09;的设计目的是保证客户端机器与服务器之间的通信。 在客户端和服务器之间进行请求-响应时&#xff0c;两种最常被用到的方法是&#xff1a;GET 和 POST。 GET - 从指定的资源请求数据。&#xff08;一般用于获取数据&#…

电脑故障扫描修复软件_电脑故障分析:电脑安装软件提示没有权限的解决方法...

我们安装软件时如果没有权限就会导致安装故障&#xff0c;最近就有用户安装软件的时候出现了无法将数值写入键software的错误提示&#xff0c;请验证您对该键拥有足够的访问权限&#xff0c;或者与您的技术支持人员联系。那么遇到这种问题该怎么办呢&#xff1f;接下来就让我们…

Nodejs 路由封装 封装一个类似 express 的路由

1、模块化的方式封装 routes.js: const http require(http); const fs require(fs); const path require(path) const url require(url) const ejs require(ejs) let getFileMime function (extname) {// 把异步读取文件方法改为同步读取文件方法let data fs.readFileSy…