console.log(`------------------------------\n----Promise基本用法\n------------------------------`)
//创建“承诺”
const promise = new Promise((resolve, reject) => {
//resolve和reject只会调用一个
//成功
// resolve(100)
//失败
reject(new Error("this is reject!"))
})
//使用Promise
promise.then((value) => {
//成功时的回调
console.log("resolved", value)
}, (error) => {
//失败时的回调
console.log("rejected", error)
})
//Promise中无异步处理,但使用Promise.then时,就是异步调用。
//也就是说会将then(resolve,reject)中的resolve和reject方法放到队列中,延后执行
console.log("end of the part")
/**成功(resolve):
end of the part
resolved 100
*/
/**失败(reject):
end of the part
rejected Error: this is reject!
at 01.promise.js:14
at new Promise ()
at Object. (01.promise.js:8)
at __webpack_require__ (bootstrap:19)
at Object. (bootstrap:83)
at __webpack_require__ (bootstrap:19)
at bootstrap:83
at bootstrap:83
*/
console.log(`------------------------------\n----Promise的ajax使用\n------------------------------`)
const ajax = function (url) {
return new Promise(function (resolve, reject) {
let xhr = new XMLHttpRequest()
xhr.open("GET", url)
xhr.responseType = "json"
xhr.onload = function () {
if (this.status === 200) {
resolve(200)
} else {
reject(this.statusText)
}
}
xhr.send()
})
}
ajax("/api/users.jsona").then((value) => {
console.log(value) //200
}, (err) => {
console.log(err) //Not Found
})
console.log(`------------------------------\n----Promise链式调用\n------------------------------`)
const ajax = function (url) {
return new Promise(function (resolve, reject) {
let xhr = new XMLHttpRequest()
xhr.open("GET", url)
xhr.responseType = "json"
xhr.onload = function () {
if (this.status === 200) {
resolve(200)
} else {
reject(this.statusText)
}
}
xhr.send()
})
}
let promise = ajax("/api/users.json")
/** then()方法返回的是Promise对象 */
let promise2 = promise.then(function (value) {
console.log(1111)
})
console.log(promise2) // Promise {}
/** 每次返回的都是一个全新的Promise对象 */
console.log(promise == promise2) //false
/** 执行下一个then()方法需要等待上一个then()方法返回的Promise对象有了明确的状态之后执行 */
let promise3 = promise2.then(function (value) {
console.log(2222)
}).then(function (value) {
console.log(5555)
}).then(function (value) {
console.log(4444)
})
/**结果
1111
2222
5555
4444
*/
/** 上一个then()方法返回的值,是下一个then()方法的回调参数 */
promise3.then(function (value) {
console.log("first:", value)
return "params test"
}).then(function (value) {
console.log("second:", value)
})
/**结果
first:undefined
seconde:params test
*/
/** 第一种方式:使用then()方法中的onReject回调函数捕获
* 捕获的是上一个返回的promise对象出现的异常
*/
ajax("/api/users.json").then(function (value) {
console.log(value)
noFunction()
}, function (err) {
console.log(err)
})
/**打印
Uncaught (in promise) ReferenceError: noFunction is not defined
at VERSION (index.js:154)
*/
/** 第二种方式:在then()方法结束后使用catch()方法
* 捕获的是当前Promise对象出现的异常
* catch()方法是then()方法的别名,catch(function(err){...}) === then(undefined,function(err){...})
*/
ajax("/api/users.json").then(function (value) {
console.log(value)
noFunction()
}).catch(function (err) {
console.log(err)
})
/**打印
ReferenceError: noFunction is not defined
at index.js:166
*/
//方式1:
ajax("/api/users.json").then(function (value) {
console.log(value)
return ajax("/error-url") //异常处
}, function (err) {
console.log(err) //没有捕获
})
//方式2::
ajax("/api/users.json").then(function (value) {
console.log(value)
return ajax("/error-url") //异常处
}).catch(function (err) {
console.log(err) //Error: Not Found at XMLHttpRequest.xhr.onload (index.js:147)
})
/** 在window上 */
window.addEventListener('unhandledrejection', event => {
const {
reason, promise } = event
// reason :Promise失败原因,一般是一个错误对象
//promise :出现异常的Promise对象
event.preventDefault()
}, false)
/** 在node上 */
process.on('unhandledRejection', (reason, promise) => {
console.log(reason, promise)
})
let promise1 = Promise.resolve("my value")
promise1.then(function (val) {
console.log(val) // my value
})
let promise2 = Promise.resolve(promise1)
console.log(promise1 === promise2) //true
Promise.resolve({
then: function (onFulfilled, onRejected) {
onFulfilled("then object to promise object")
}
})
.then(function (value) {
console.log(value) //then object to promise object
})
Promise.reject(new Error("my error in reject static function"))
.catch(function (err) {
console.log(err) //Error: my error in reject static function
})
(users.json)
[
{
"name": "asd",
"age": 32
},
{
"name": "bbb",
"age": 12
}
]
(classes.json)
[
{
"className": "A1班",
"level": "三年级"
},
{
"className": "A5班",
"level": "二年级"
}
]
(js)
const ajax = function (url) {
return new Promise(function (resolve, reject) {
let xhr = new XMLHttpRequest()
xhr.open("GET", url)
xhr.responseType = "json"
xhr.onload = function () {
if (this.status === 200) {
resolve(this.response)
} else {
reject(this.statusText)
}
}
xhr.send()
})
}
//全部成功,才会返回成功
//传一个Promise对象数组
let promiseAll = Promise.all([
ajax("/api/users.json"),
ajax("/api/classes.json")
])
//返回的是Promise结果数组
promiseAll.then(function (values) {
console.log(values) // [Array(2), Array(2)]
})
//有一个失败,则都会失败
let promiseAllFail = Promise.all([
ajax("/api/users.json"),
ajax("/api/none-file.json") //异常处
])
promiseAllFail.then(function (values) {
console.log(values)
}).catch(function (err) {
console.log(err) //Not Found
})
(urls.json)
{
"users": "/api/users.json",
"classes": "/api/classes.json"
}
(js)
ajax("/api/urls.json")
.then(res => {
const urls = Object.values(res)
const promiseArray = urls.map(url => ajax(url))
return Promise.all(promiseArray)
})
.then(res => {
console.log(res) //[Array(2), Array(2)]
})
const ajax = function (url) {
return new Promise(function (resolve, reject) {
let xhr = new XMLHttpRequest()
xhr.open("GET", url)
xhr.responseType = "json"
xhr.onload = function () {
if (this.status === 200) {
resolve(this.response)
} else {
reject(this.statusText)
}
}
xhr.send()
})
}
const normal = ajax("/api/users.json")
const timeout = new Promise((resolve, reject) => {
setTimeout(() => {
reject("it is timeout!")
}, 500)
})
Promise.race([
normal,
timeout
])
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err) // 在3G网测试下:it is timeout!
})
console.log("programming start")
setTimeout(() => {
//setTimeout方法为宏任务,会在本轮任务全部结束后执行
console.log("setTimeout")
new Promise((resolve, reject) => {
console.log("inner promise 1")
resolve("ok")
})
.then(res => {
console.log("inner promise 2")
})
}, 0)
new Promise((resolve, reject) => {
//Promise是微任务,会在本轮任务末尾执行
console.log("promise 1")
resolve("ok")
})
.then(res => {
console.log("promise 2")
})
.then(res => {
console.log("promise 3")
})
console.log("programming end")
/**结果
programming start
promise 1
programming end
promise 2
promise 3
setTimeout
inner promise 1
inner promise 2
*/