回调地狱(callback-hell):
回调地狱实例图.png此程序不能保证执行的先后顺序:
fs.readFile('./data/a.txt','utf8',function(err,data){
if (err) {
throw err
}
console.log(data)
})
fs.readFile('./data/b.txt','utf8',function(err,data){
if (err) {
throw err
}
console.log(data)
})
fs.readFile('./data/c.txt','utf8',function(err,data){
if (err) {
throw err
}
console.log(data)
})
解决方式(嵌套):
var fs = require('fs')
fs.readFile('./data/a.txt', 'utf8', function (err, data) {
if (err) {
// return console.log('读取失败')
// 抛出异常
// 1. 阻止程序的执行
// 2. 把错误消息打印到控制台
throw err
}
console.log(data)
fs.readFile('./data/b.txt', 'utf8', function (err, data) {
if (err) {
// return console.log('读取失败')
// 抛出异常
// 1. 阻止程序的执行
// 2. 把错误消息打印到控制台
throw err
}
console.log(data)
fs.readFile('./data/c.txt', 'utf8', function (err, data) {
if (err) {
// return console.log('读取失败')
// 抛出异常
// 1. 阻止程序的执行
// 2. 把错误消息打印到控制台
throw err
}
console.log(data)
})
})
})
解决回调地狱(Promise)
promise-基本语法i:
//创建 Promise容器
//Promiser容器一旦创建,就开始执行里面的代码
var p1 = new Promise(function (resolve, reject) {
console.log(3)
fs.readFile('./data/a.txt', 'utf8', function (err, data) {
if (err) {
//容器任务执行成功了!
reject(err)
//把容器的penging 状态变为Rejected
//这里调用的 reject方法实际相当于调用了then方法的第二个函数参数
} else {
//容器任务执行失败了了!
//console.log(data)
resolve(data)
//把容器的penging状态改为成功Rwsolved!
//这里调用的resolve方法实际就是then方法传递的那个function
}
})
})
var p2 = new Promise(function (resolve, reject) {
fs.readFile('./data/b.txt', 'utf8', function (err, data) {
if (err) {
reject(err)
} else {
resolve(data)
}
})
})
var p3 = new Promise(function (resolve, reject) {
fs.readFile('./data/c.txt', 'utf8', function (err, data) {
if (err) {
reject(err)
} else {
resolve(data)
}
})
})
//p1就是promise容器
//当p1成功了 然后(then)做指定的操作
//that方法接受到的function就是 resolve函数
p1
.then(function (data) {
console.log(data)
// 当 p1 读取成功的时候
// 当前函数中 return 的结果就可以在后面的 then 中 function 接收到
// 当你 return 123 后面就接收到 123
// return 'hello' 后面就接收到 'hello'
// 没有 return 后面收到的就是 undefined
// 上面那些 return 的数据没什么卵用
// 真正有用的是:我们可以 return 一个 Promise 对象
// 当 return 一个 Promise 对象的时候,后续的 then 中的 方法的第一个参数会作为 p2 的 resolve
//
return p2
}, function (err) {
console.log('读取文件失败了', err)
})
.then(function (data) {
console.log(data)
return p3
})
.then(function (data) {
console.log(data)
console.log('end')
})
Peoniseapi图示.png
promise链式调用..png
封装promise-API:
var fs = require('fs')
//封装
function pReadFile(filePath) {
return new Promise(function (resolve, reject) {
fs.readFile(filePath, 'utf8', 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)
})
promise使用场景:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<form action="00-js中的一等公民函数.js" id="user_form">
</form>
<script type="text/template" id="tpl">
<div>
<label for="">用户名</label>
<input type="text" value="{{ user.username }}">
</div>
<div>
<label for="">年龄</label>
<input type="text" value="{{ user.age }}">
</div>
<div>
<label for="">职业</label>
<select name="" id="">
{{ each jobs }} {{ if user.job === $value.id }}
<option value="{{ $value.id }}" selected>{{ $value.name }}</option>
{{ else }}
<option value="{{ $value.id }}">{{ $value.name }}</option>
{{ /if }} {{ /each }}
</select>
</div>
</script>
<script src="node_modules/art-template/lib/template-web.js"></script>
<script src="node_modules/jquery/dist/jquery.js"></script>
<script>
// 用户表
// 其中一个接口获取用户数据
// 职业:2
// 职业信息表
// 其中一个接口获取所有的职业信息
// get('http://127.0.0.1:3000/users/4', function (userData) {
// get('http://127.0.0.1:3000/jobs', function (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/4')
// .then(function (user) {
// data.user = user
// return $.get('http://127.0.0.1:3000/jobs')
// })
// .then(function (jobs) {
// data.jobs = jobs
// var htmlStr = template('tpl', data)
// document.querySelector('#user_form').innerHTML = htmlStr
// })
// var data = {}
// pGet('http://127.0.0.1:3000/users/4')
// .then(function (user) {
// data.user = user
// return pGet('http://127.0.0.1:3000/jobs')
// })
// .then(function (jobs) {
// data.jobs = jobs
// var htmlStr = template('tpl', data)
// document.querySelector('#user_form').innerHTML = htmlStr
// })
// pGet('http://127.0.0.1:3000/users/4', function (data) {
// console.log(data)
// })
pGet('http://127.0.0.1:3000/users/4')
.then(function (data) {
console.log(data)
})
function pGet(url, callback) {
return new Promise(function (resolve, reject) {
var oReq = new XMLHttpRequest()
// 当请求加载成功之后要调用指定的函数
oReq.onload = function () {
// 我现在需要得到这里的 oReq.responseText
callback && callback(JSON.parse(oReq.responseText))
resolve(JSON.parse(oReq.responseText))
}
oReq.onerror = function (err) {
reject(err)
}
oReq.open("get", url, true)
oReq.send()
})
}
// 这个 get 是 callback 方式的 API
// 可以使用 Promise 来解决这个问题
function get(url, callback) {
var oReq = new XMLHttpRequest()
// 当请求加载成功之后要调用指定的函数
oReq.onload = function () {
// 我现在需要得到这里的 oReq.responseText
callback(oReq.responseText)
}
oReq.open("get", url, true)
oReq.send()
}
</script>
</body>
</html>
Promise操作数据库(用户注册):
// 用户注册
// 1. 判断用户是否存在
// 如果已存在,结束注册
// 如果不存在,注册(保存一条用户信息)
User.find()
.then(function (data) {
console.log(data)
})
User.findOne({ username: 'aaa' }, function (user) {
if (user) {
console.log('已存在')
} else {
new User({
username: 'aaa',
password: '123',
email: 'dsadas'
}).save(function () {
})
}
})
User.findOne({
username: 'aaa'
})
.then(function (user) {
if (user) {
// 用户已存在,不能注册
console.log('用户已存在')
} else {
// 用户不存在,可以注册
return new User({
username: 'aaa',
password: '123',
email: 'dsadas'
}).save()
}
})
.then(function (ret) {
})
网友评论