异步编程:
- fs文件操作:
require('fs').readFile('./index.html', (err,data)=>{})
- 数据库操作
- Ajax网络请求:
$.get('/server', (data)=>{})
- 定时器:
setTimeout(()=>{}, 2000)
旧的: 必须在启动异步任务前指定
promise: 启动异步任务 => 返回promise对象 => 给promise对象绑定回调函数(甚至可以在异步任务结束后指定/多个)
回调地狱:回调函数嵌套调用, 外部回调函数异步执行的结果是嵌套的回调执行的条件
回调地狱的缺点:
实例对象中的一个属性 『PromiseState
』
pending
未决定的resolved
/ fullfilled
成功rejected
失败实例对象中的另一个属性 『PromiseResult
』,保存着异步任务『成功/失败』的结果
resolve
reject
html<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Promise初体验</title>
<link crossorigin='anonymous' href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<h2 class="page-header">Promise 初体验</h2>
<button id="btn" class="btn btn-primary">点击抽奖</button>
</div>
<script>
// 生成随机数
function rand(m, n) {
return Math.ceil(Math.random() * (n-m+1)) + m-1
}
/**
点击按钮, 1s 后显示是否中奖(30%概率中奖)
若中奖弹出 恭喜中奖
若未中奖弹出 再接再厉
*/
// 获取元素对象
const btn = document.getElementById('btn')
// 绑定单击事件
btn.addEventListener('click', function() {
// 定时器
/* setTimeout(() => {
// 获取从1 - 100的一个随机数
let n = rand(1, 100)
// 判断
if(n <= 30) {
alert('恭喜中奖')
} else {
alert('再接再厉')
}
}, 1000) */
// Promise 形式实现
// resolve 解决 函数类型的数据
// reject 拒绝 函数类型的数据
const p = new Promise((resolve, reject) => {
setTimeout(() => {
// 获取从1 - 100的一个随机数
let n = rand(1, 100)
// 判断
if(n <= 30) {
resolve(n)
} else {
reject(n)
}
}, 1000)
})
p.then((value) => {
alert('恭喜中奖,号码为' + value)
}, (reason) => {
alert('再接再厉,编号为' + reason)
})
})
</script>
</body>
</html>
jsconst fs = require('fs')
// 回调函数形式
/* fs.readFile('./resource/content.txt', (err, data) => {
if(err) throw err
console.log(data.toString())
}) */
let p = new Promise((resolve, reject) => {
fs.readFile('./resource/content.txt', (err, data) => {
if(err) reject(err)
resolve(data)
})
})
p.then(value => {
console.log(value.toString())
}, reason => {
console.log(reason)
})
html<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ajax请求</title>
<link crossorigin='anonymous' href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<h2 class="page-header">Promise Ajax请求</h2>
<button id="btn" class="btn btn-primary">发送请求</button>
</div>
<script>
// 获取元素对象
const btn = document.getElementById('btn')
// 绑定单击事件
btn.addEventListener('click', function() {
const p = new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.open('GET', 'https://api.apiopen.top/getJoke')
xhr.send()
xhr.onreadystatechange = function() {
if(xhr.readyState === 4) {
if(xhr.status >=200 && xhr.status < 300) {
resolve(xhr.response)
} else {
reject(xhr.status)
}
}
}
})
p.then((value) => {
console.log(value)
}, (reason) => {
console.log(reason)
})
})
</script>
</body>
</html>
js/**
* 封装一个函数 myReadFile 读取文件内容
* 参数: path 文件路径
* 返回: promise 对象
*/
function myReadFile(path) {
return new Promise((resolve, reject) => {
require('fs').readFile(path, (err, data) => {
if(err) reject(err)
resolve(data)
})
})
}
myReadFile('./resource/content.txt').then((value) => {
console.log(value.toString())
}, (reason) => {
console.log(reason)
})
js/**
* util.promisify 方法
*/
const util = require('util')
const fs = require('fs')
let myReadFile = util.promisify(fs.readFile)
myReadFile('./resource/content.txt').then((value) => {
console.log(value.toString())
}, (reason) => {
console.log(reason)
})
html<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Promise封装AJAX操作</title>
</head>
<body>
<script>
/**
* 封装一个函数 sendAjax 发送 GET AJAX 请求
* 参数 URL
* 返回结果 Promise 对象
*/
function sendAjax(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.responseType = 'json'
xhr.open('GET', url)
xhr.send()
xhr.onreadystatechange = function() {
if(xhr.readyState === 4) {
if(xhr.status >=200 && xhr.status < 300) {
resolve(xhr.response)
} else {
reject(xhr.status)
}
}
}
})
}
sendAjax('https://api.apiopen.top/getJoke').then((value) => {
console.log(value)
}, (reason) => {
console.log(reason)
})
</script>
</body>
</html>
Promise
构造函数Promise (excutor) {}
executor
函数: 执行器 (resolve, reject) => {}
resolve
函数: 内部定义成功时我们调用的函数 value => {}
reject
函数: 内部定义失败时我们调用的函数 reason => {}
说明: executor
会在Promise
内部立即同步调用,异步操作在执行器中执行
Promise.prototype.then
方法(onResolved, onRejected) => {}
onResolved
函数: 成功的回调函数 (value) => {}
onRejected
函数: 失败的回调函数 (reason) => {}
说明: 指定用于得到成功 value
的成功回调和用于得到失败 reason
的失败回调返回一个新的 Promise
对象
Promise.prototype.catch
方法(onRejected) => {}
onRejected
函数: 失败的回调函数 (reason) => {}
说明: then()
的语法糖, 相当于: then(undefined, onRejected)
Promise.resolve
方法(value) => {}
,属于Promise函数对象,不属于实例对象
value
: 成功的数据或 Promise
对象
如果传入的参数为 非
Promise
类型的对象, 则返回的结果为成功Promise
对象如果传入的参数为
Promise
对象, 则参数的结果决定了resolve
的结果
jslet p1 = Promise.resolve(521)
console.log(p1)
//如果传入的参数为 非Promise类型的对象, 则返回的结果为成功promise对象
//如果传入的参数为 Promise 对象, 则参数的结果决定了 resolve 的结果
let p2 = Promise.resolve(new Promise((resolve, reject) => {
// resolve('OK')
reject('Error')
}));
console.log(p2)
p2.catch(reason => {
// console.log(reason);
})
Promise.reject
方法(reason) => {}
,属于Promise函数对象,不属于实例对象
reason
: 失败的原因
说明: 返回一个失败的 promise
对象
Promise.all
方法(promises) => {}
promises
: 包含 n
个 promise
的数组
说明: 返回一个新的 promise
,只有所有的 promise
都成功才成功, 只要有一个失败了就直接失败
jslet p1 = new Promise((resolve, reject) => {
resolve('OK');
})
let p2 = Promise.resolve('Success')
let p3 = Promise.resolve('Oh Yeah')
let p4 = Promise.reject('Error')
const result = Promise.all([p1, p2, p3])
const fResult = Promise.all([p1, p2, p3, p4])
console.log(result);
console.log(fResult)
Promise.race
方法(promises) => {}
promises
: 包含 n
个 promise
的数组
说明: 返回一个新的 promise
,第一个完成的 promise
的结果状态就是最终的结果状态
使用场景:ajax请求和超时回调,ajax在超时回调执行前完成,显示回调结果,否则显示请求超时
jslet p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('OK')
}, 1000);
})
let p2 = Promise.resolve('Success')
let p3 = Promise.resolve('Oh Yeah')
//调用
const result = Promise.race([p1, p2, p3])
console.log(result)
如何改变 promise 的状态?
resolve(value)
:如果当前是 pending
就会变为 resolved
reject(reason)
:如果当前是 pending
就会变为 rejected
throw 'error_str'
抛出异常:如果当前是 pending
就会变为 rejected
(异步不能throw
,捕获不到)一个 promise
指定多个成功/失败回调函数, 都会调用吗?(用then()
方法为一个promise
对象指定多个回调)
promise
改变为对应状态时都会调用改变 promise
状态和指定回调函数谁先谁后?
都有可能, 正常情况下是先指定回调再改变状态, 但也可以先改状态再指定回调
如何先改状态再指定回调?
在执行器中直接调用 resolve()
/reject()
延迟更长时间才调用 then()
什么时候才能得到数据?
promise.then()
返回的新 promise
的结果状态由什么决定?
then()
指定的回调函数执行的结果决定promise
变为 rejected
,reason
为抛出的异常promise
的任意值,新promise
变为resolved
,value
为返回的值promise
,此promise
的结果就会成为新promise
的结果promise
如何串连多个操作任务
promise
的 then()
返回一个新的 promise
,可以开成 then()
的链式调用
通过 then
的链式调用串连多个同步/异步任务
jslet p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('OK')
}, 1000)
})
p.then(value => {
return new Promise((resolve, reject) => {
resolve("success")
})
}).then(value => {
console.log(value)
}).then(value => {
console.log(value)
})
promise
异常穿透
当使用 promise
的 then
链式调用时,可以在最后指定失败的回调
jsp.then(value => {
// console.log(111)
throw '失败啦!';
}).then(value => {
console.log(222)
}).then(value => {
console.log(333)
}).catch(reason => {
console.warn(reason)
});
前面任何操作出了异常,都会传到最后失败的回调中处理
如何中断 promise
链
promise
的 then
链式调用时, 在中间中断, 不再调用后面的回调函数pendding
状态的 promise 对象jsp.then(value => {
console.log(111)
//有且只有一个方式
return new Promise(() => {})
}).then(value => {
console.log(222)
}).then(value => {
console.log(333)
}).catch(reason => {
console.warn(reason)
});
js// 声明构造函数
function Promise(executor) { // executor:Promise声明时接收的形参(执行器函数)
}
// 添加then方法
Promise.prototype.then = function(onResolved, onRejected) {
}
jsfunction Promise(executor) {
// 添加属性
this.PromsieState = 'pending'
this.PromiseResult = null
// 提前保存this值
const self = this
// resolve函数
function resolve(data) {
// 1.修改对象的状态 (PromiseState)
self.PromsieState = 'fulfilled' // 此处this默认指向window
// 2.设置对象结果值 (PromiseResult)
self.PromiseResult = data
}
// reject函数
function reject(data) {
// 1.修改对象的状态 (PromiseState)
self.PromsieState = 'rejected'
// 2.设置对象结果值 (PromiseResult)
self.PromiseResult = data
}
// 同步调用 执行器函数
executor(resolve, reject)
}
jstry {
// 同步调用 执行器函数
executor(resolve, reject)
} catch (e) {
reject(e)
}
在resolve()
和reject()
添加状态判断
js// 判断状态
if (self.PromsieState !== 'pending') return
jsPromise.prototype.then = function(onResolved, onRejected) {
// 调用回调函数,依据:PromiseState
if (this.PromsieState === 'fulfilled') {
onResolved(this.PromiseResult)
}
if (this.PromsieState === 'rejected') {
onRejected(this.PromiseResult)
}
}
为Promise对象增加属性:this.callback = {}
在then方法中判断pending状态:
js// 判断pending状态
if (this.PromiseState === 'pending') {
// 保存回调函数
this.callback = { // 可简写
onResolved: onResolved,
onRejected: onRejected
}
}
resolve函数和reject函数分别调用对应的回调函数:
js// 调用成功的回调函数
if (self.callback.onResolved) {
self.callback.onResolved(data)
}
// 调用失败的回调函数
if (self.callback.onRejected) {
self.callback.onRejected(data)
}
将callback修改为数组:this.callbacks = []
修改then方法中判断pending状态:
jsif (this.PromiseState === 'pending') {
// 保存回调函数
this.callbacks.push({
onResolved,
onRejected
})
}
resolve函数和reject函数分别调用对应的回调函数:
js// 调用成功的回调函数
self.callbacks.forEach(item => {
item.onResolved(data)
})
// 调用失败的回调函数
self.callbacks.forEach(item => {
item.onRejected(data)
})
判断onResolved
的返回值,是Promise对象则then,非Promise对象则resolve,使用try-catch抛出异常
jsPromise.prototype.then = function(onResolved, onRejected) {
return new Promise((resolve, reject) => {
// 调用回调函数,依据:PromiseState
if (this.PromiseState === 'fulfilled') {
try {
let result = onResolved(this.PromiseResult)
if(result instanceof Promise) {
// 如果是Promise类型的对象
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
// 结果的对象状态为 成功
resolve(result)
}
} catch (e) {
reject(e)
}
}
if (this.PromiseState === 'rejected') {
try {
let result = onRejected(this.PromiseResult)
if(result instanceof Promise) {
// 如果是Promise类型的对象
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
// 结果的对象状态为 成功
resolve(result)
}
} catch (e) {
reject(e)
}
}
// 判断pending状态
if (this.PromiseState === 'pending') {
// 保存回调函数
this.callbacks.push({
onResolved,
onRejected
})
}
})
}
状态为pending时
js// 判断pending状态
if (this.PromiseState === 'pending') {
// 保存回调函数
this.callbacks.push({
onResolved: function() {
try {
let result = onResolved(self.PromiseResult)
if(result instanceof Promise) {
// 如果是Promise类型的对象
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
// 结果的对象状态为 成功
resolve(result)
}
} catch (e) {
reject(e)
}
},
onRejected: function() {
try {
let result = onRejected(self.PromiseResult)
if(result instanceof Promise) {
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
resolve(result)
}
} catch (e) {
reject(e)
}
}
})
}
将重复的代码块进行封装
jsPromise.prototype.then = function(onResolved, onRejected) {
const self = this
return new Promise((resolve, reject) => {
function callback(type) {
try {
let result = type(self.PromiseResult)
if(result instanceof Promise) {
// 如果是Promise类型的对象
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
// 结果的对象状态为 成功
resolve(result)
}
} catch (e) {
reject(e)
}
}
// 调用回调函数,依据:PromiseState
if (this.PromiseState === 'fulfilled') {
callback(onResolved)
}
if (this.PromiseState === 'rejected') {
callback(onRejected)
}
// 判断pending状态
if (this.PromiseState === 'pending') {
// 保存回调函数
this.callbacks.push({
onResolved: function() {
callback(onResolved)
},
onRejected: function() {
callback(onRejected)
}
})
}
})
}
js// 添加catch方法
Promise.prototype.catch = function (onRejected) {
return this.then(undefined, onRejected)
}
then方法中判断回调函数参数
js// 判断回调函数参数
if(onRejected !== 'function') {
onRejected = reason => {
throw reason
}
}
if(onResolved !== 'function') {
onResolved = value => value
//value => value <===> value => { return value }
}
js// 添加resolve方法
Promise.resolve = function(value) {
// 返回Promise对象
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
// 状态设置为成功
resolve(value)
}
})
}
// 添加reject方法
Promise.reject = function(reason) {
return new Promise((resolve, reject) => {
reject(reason)
})
}
js// 添加all方法
Promise.all = function(promises) {
return new Promise((resolve, reject) => {
// 声明计数器
let count = 0
// 保存对象成功的数组
let arr = []
// 遍历
for (let i = 0; i < promises.length; i++) {
promises[i].then(v => {
count++
// 将当前promise对象成功的结果存入数组中
arr[i] = v
if (count === promises.length) {
// 修改状态
resolve(arr)
}
}, r => {
reject(r)
})
}
})
}
js// 添加race方法
Promise.race = function(promises) {
return new Promise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
promises[i].then(v => {
resolve(v)
}, r => {
reject(r)
})
}
})
}
“回调函数『异步执行』”指then方法指定的回调函数是异步执行的
html<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Promise回调函数『异步执行』</title> </head> <body> <script> let p1 = new Promise((resolve, reject) => { resolve('OK') console.log('111') }) p1.then(value => { console.log('222') }) console.log('333') </script> </body> </html>
执行结果:
then方法中的回调是异步执行的,需要同步执行完毕后再执行
对then方法与构造函数中的resolve、reject在调用回调时,添加定时器:
jsfunction Promise(executor) {
...
// resolve函数
function resolve(data) {
...
// 调用成功的回调函数
// 异步
setTimeout(() => {
self.callbacks.forEach(item => {
item.onResolved(data)
})
})
}
// reject函数
function reject(data) {
...
// 调用失败的回调函数
setTimeout(() => {
self.callbacks.forEach(item => {
item.onRejected(data)
})
})
}
...
}
Promise.prototype.then = function(onResolved, onRejected) {
...
return new Promise((resolve, reject) => {
...
// 调用回调函数,依据:PromiseState
if (this.PromiseState === 'fulfilled') {
setTimeout(() => {
callback(onResolved)
})
}
if (this.PromiseState === 'rejected') {
setTimeout(() => {
callback(onResolved)
})
}
...
})
}
javascript// 声明构造函数
function Promise(executor) {
// 添加属性
this.PromiseState = 'pending'
this.PromiseResult = null
this.callbacks = []
// 提前保存this值
const self = this
// resolve函数
function resolve(data) {
// 判断状态
if (self.PromiseState !== 'pending') return
// 1.修改对象的状态 (PromiseState)
self.PromiseState = 'fulfilled' // 此处this默认指向window
// 2.设置对象结果值 (PromiseResult)
self.PromiseResult = data
// 调用成功的回调函数
// 异步
setTimeout(() => {
self.callbacks.forEach(item => {
item.onResolved(data)
})
})
}
// reject函数
function reject(data) {
// 判断状态
if (self.PromiseState !== 'pending') return
// 1.修改对象的状态 (PromiseState)
self.PromiseState = 'rejected'
// 2.设置对象结果值 (PromiseResult)
self.PromiseResult = data
// 调用失败的回调函数
setTimeout(() => {
self.callbacks.forEach(item => {
item.onRejected(data)
})
})
}
try {
// 同步调用 执行器函数
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
// 添加then方法
Promise.prototype.then = function(onResolved, onRejected) {
const self = this
// 判断回调函数参数
if(typeof onRejected !== 'function') {
onRejected = reason => {
throw reason
}
}
if(typeof onResolved !== 'function') {
onResolved = value => value
//value => value <===> value => { return value }
}
return new Promise((resolve, reject) => {
function callback(type) {
try {
let result = type(self.PromiseResult)
if(result instanceof Promise) {
// 如果是Promise类型的对象
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
// 结果的对象状态为 成功
resolve(result)
}
} catch (e) {
reject(e)
}
}
// 调用回调函数,依据:PromiseState
if (this.PromiseState === 'fulfilled') {
setTimeout(() => {
callback(onResolved)
})
}
if (this.PromiseState === 'rejected') {
setTimeout(() => {
callback(onResolved)
})
}
// 判断pending状态
if (this.PromiseState === 'pending') {
// 保存回调函数
this.callbacks.push({
onResolved: function() {
callback(onResolved)
},
onRejected: function() {
callback(onRejected)
}
})
}
})
}
// 添加catch方法
Promise.prototype.catch = function(onRejected) {
return this.then(undefined, onRejected)
}
// 添加resolve方法
Promise.resolve = function(value) {
// 返回Promise对象
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
// 状态设置为成功
resolve(value)
}
})
}
// 添加reject方法
Promise.reject = function(reason) {
return new Promise((resolve, reject) => {
reject(reason)
})
}
// 添加all方法
Promise.all = function(promises) {
return new Promise((resolve, reject) => {
// 声明计数器
let count = 0
// 保存对象成功的数组
let arr = []
// 遍历
for (let i = 0; i < promises.length; i++) {
promises[i].then(v => {
count++
// 将当前promise对象成功的结果存入数组中
arr[i] = v
if (count === promises.length) {
// 修改状态
resolve(arr)
}
}, r => {
reject(r)
})
}
})
}
// 添加race方法
Promise.race = function(promises) {
return new Promise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
promises[i].then(v => {
resolve(v)
}, r => {
reject(r)
})
}
})
}
jsclass Promise {
constructor(executor) {
// 添加属性
this.PromiseState = 'pending'
this.PromiseResult = null
this.callbacks = []
// 提前保存this值
const self = this
// resolve函数
function resolve(data) {
// 判断状态
if (self.PromiseState !== 'pending') return
// 1.修改对象的状态 (PromiseState)
self.PromiseState = 'fulfilled' // 此处this默认指向window
// 2.设置对象结果值 (PromiseResult)
self.PromiseResult = data
// 调用成功的回调函数
// 异步
setTimeout(() => {
self.callbacks.forEach(item => {
item.onResolved(data)
})
})
}
// reject函数
function reject(data) {
// 判断状态
if (self.PromiseState !== 'pending') return
// 1.修改对象的状态 (PromiseState)
self.PromiseState = 'rejected'
// 2.设置对象结果值 (PromiseResult)
self.PromiseResult = data
// 调用失败的回调函数
setTimeout(() => {
self.callbacks.forEach(item => {
item.onRejected(data)
})
})
}
try {
// 同步调用 执行器函数
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
then(onResolved, onRejected) {
const self = this
// 判断回调函数参数
if(typeof onRejected !== 'function') {
onRejected = reason => {
throw reason
}
}
if(typeof onResolved !== 'function') {
onResolved = value => value
//value => value <===> value => { return value }
}
return new Promise((resolve, reject) => {
function callback(type) {
try {
let result = type(self.PromiseResult)
if(result instanceof Promise) {
// 如果是Promise类型的对象
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
// 结果的对象状态为 成功
resolve(result)
}
} catch (e) {
reject(e)
}
}
// 调用回调函数,依据:PromiseState
if (this.PromiseState === 'fulfilled') {
setTimeout(() => {
callback(onResolved)
})
}
if (this.PromiseState === 'rejected') {
setTimeout(() => {
callback(onResolved)
})
}
// 判断pending状态
if (this.PromiseState === 'pending') {
// 保存回调函数
this.callbacks.push({
onResolved: function() {
callback(onResolved)
},
onRejected: function() {
callback(onRejected)
}
})
}
})
}
catch(onRejected) {
return this.then(undefined, onRejected)
}
static resolve(value) {
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
// 状态设置为成功
resolve(value)
}
})
}
static reject(reason) {
return new Promise((resolve, reject) => {
reject(reason)
})
}
static all(promises) {
return new Promise((resolve, reject) => {
// 声明计数器
let count = 0
// 保存对象成功的数组
let arr = []
// 遍历
for (let i = 0; i < promises.length; i++) {
promises[i].then(v => {
count++
// 将当前promise对象成功的结果存入数组中
arr[i] = v
if (count === promises.length) {
// 修改状态
resolve(arr)
}
}, r => {
reject(r)
})
}
})
}
static race(promises) {
return new Promise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
promises[i].then(v => {
resolve(v)
}, r => {
reject(r)
})
}
})
}
}
函数的返回值为Promise对象:
jsasync function main(){
//1. 如果返回值是一个非Promise类型的数据
// return 521;
//2. 如果返回的是一个Promise对象
// return new Promise((resolve, reject) => {
// // resolve('OK');
// reject('Error');
// });
//3. 抛出异常
throw "Oh NO";
}
let result = main();
console.log(result);
await右侧的表达式一般为Promise对象,但也可以是其他的值:
注意:
await必须写在async函数中,但async函数中可以没有await表达式
jsasync function main() {
let p = Promise.resolve('ok')
// 1.右侧为promise的情况
let res = await p
console.log(res)
// 2.右侧为其他类型的数据
res = await 20
console.log(res)
// 3.如果promise是失败的状态
try {
let p2 = Promise.reject('error')
res = await p2
} catch (e) {
console.log(e)
}
}
使用fs模块从三个文件中读取内容并拼接
jsconst fs = require('fs')
// 回调函数的方式
fs.readFile('./resource/1.html', (err, data1) => {
if(err) throw err
fs.readFile('./resource/2.html', (err, data2) => {
if(err) throw err
fs.readFile('./resource/3.html', (err, data3) => {
if(err) throw err
console.log(data1 + data2 + data3)
})
})
})
jsconst fs = require('fs')
const util = require('util')
const myReadFile = util.promisify(fs.readFile)
// async + await
async function main() {
try {
let data1 = await myReadFile('./resource/1.html')
let data2 = await myReadFile('./resource/2.html')
let data3 = await myReadFile('./resource/3.html')
console.log(data1 + data2 + data3)
} catch (e) {
console.log(e)
}
}
main()
html<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Ajax</title>
</head>
<body>
<button>点击获取段子</button>
<script>
function sendAjax(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.responseType = 'json'
xhr.open('GET', url)
xhr.send()
xhr.onreadystatechange = function() {
if(xhr.readyState === 4) {
if(xhr.status >=200 && xhr.status < 300) {
resolve(xhr.response)
} else {
reject(xhr.status)
}
}
}
})
}
const btn = document.querySelector('button')
btn.addEventListener('click', async function() {
let result = await sendAjax('https://api.apiopen.top/getJoke')
console.log(result)
})
</script>
</body>
</html>
本文作者:Morales
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 License 许可协议。转载请注明出处!