《Promise方法使用介绍》
https://www.jianshu.com/p/d8a901dd72ac
// 执行顺序
var p41 = new Promise((resolve, reject) => {
reject('p41 error')
console.log('p41---------')
}).catch(err => {
console.log('hahhahah')
})
var p42 = new Promise((resolve, reject) => {
reject('p42 err')
console.log('p42---------')
}).catch(err => {
console.log('kekekeke')
return err;
})
var p43 = new Promise((resolve, reject) => {
reject('p43 err')
console.log('p43---------')
}).catch(err => {
console.log('xixixi')
return err;
})
// 返回第一个完成的 promise 值
Promise.race([p43, p41, p42]).then((res) => {
console.log('res', res)
}, (err) => {
console.log('err', err) // p41 error
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 基本使用
让一个函数拥有 promise 功能,只需让其返回一个promise即可。
function myAsyncFunction(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.onload = () => resolve(xhr.responseText);
xhr.onerror = () => reject(xhr.statusText);
xhr.send();
});
};
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# Promise.then()
# Promise.catch()
# Promise.finally()
# Promise.resolve()
返回一个状态为 fulfilled 的 Promise 对象
# 基础用法
Promise.resolve('Hello').then((res)=> {
console.log(res); // Hello
})
1
2
3
2
3
# 应用场景
可以将现有对象专为Promise对象
var jsPromise = Promise.resolve($.ajax('/whatever.json'));
console.log(jsPromise) // Promise
1
2
2
# 使用注意
- 参数是一个 Promise 实例:Promise.resolve将不做任何修改、原封不动地返回这个实例。
var p1 = new Promise((resolve, reject) => {
resolve('p1 success')
})
Promise.resolve(p1) // Promise 实例
1
2
3
4
2
3
4
- 参数是一个thenable对象(具有then方法的对象):将这个对象转为 Promise 对象,然后就立即执行thenable对象的then方法
var thenable = {
then: function(resolve, reject) {
resolve(42);
}
};
var p1 = Promise.resolve(thenable)
console.log(p1) // status: fulfilled,value: 42
p1.then(res => {
console.log(res) // 42
})
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
- 参数不是具有then方法的对象,或根本就不是对象:返回一个新的 Promise 对象,状态为resolved
var normalObj = {
name: 'jack'
};
var p2 = Promise.resolve(normalObj)
console.log(p2) // status: fulfilled,value: { name: 'jack'}
p2.then(res => {
console.log(res) // { name: 'jack'}
})
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
- 不带有任何参数:直接返回一个resolved状态的 Promise 对象。
const p = Promise.resolve();
p.then(function () {
// ...
});
1
2
3
4
5
2
3
4
5
- 立即resolve的 Promise 对象,是在本轮“事件循环”(event loop)的结束时,而不是在下一轮“事件循环”的开始时。
原因:因为promise.resolve后的方法是属于微任务,所以会在当轮事件循环的宏任务结束后按顺序执行微任务
setTimeout(function () {
console.log('three');
}, 0);
Promise.resolve().then(function () {
console.log('two');
});
console.log('one');
// one
// two
// three
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# Promise.reject()
返回一个状态为 rejected 的 Promise 对象
# 基础用法
Promise.reject('Error').then(null, (err) =>{
console.log(err); // Error
})
Promise.reject('Error').catch((err) =>{
console.log(err); // Error
})
1
2
3
4
5
6
2
3
4
5
6
# Promise.all()
所有都成功,才会resolve,只要有一个失败,就触发reject
# 基础用法
var p11 = new Promise((resolve, reject) => {
resolve('p11 success');
})
var p12 = new Promise((resolve, reject) => {
setTimeout(() =>{
resolve('p12 success');
}, 1000)
})
var p13 = "123";
var p14 = new Promise((resolve, reject) => {
setTimeout(() =>{
reject('p14 error');
}, 2000)
})
// 传入一个 promise 数组
Promise.all([p11, p12, p13]).then((res) => {
console.log(res) // 延迟 1s 后输出 -> ["p11 success", "p12 success", "123"]
})
// 数组中含有一个 rejected 状态的promise
Promise.all([p11, p12, p13, p14]).catch((err) => {
console.log(err) // 延迟 2s 后输出 -> p14 error
})
// 传入的 promise 没有resolve 状态
Promise.all([p14]).catch((res) => {
console.log(res) // p14 error
})
// 传入一个字符串
var str = "123"
Promise.all(str).then((res) => {
console.log(res) // ["1", "2", "3"]
})
// 传入一个不含promise的数组
var arr = [1, "b", {}]
Promise.all(arr).then((res) => {
console.log(res) // [1, "b", {}]
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# 使用注意
- 注意,如果作为参数的 Promise 实例,自己定义了catch方法,那么它一旦被rejected,并不会触发Promise.all()的catch方法。
var p11 = new Promise((resolve, reject) => {
resolve('p11 success');
})
.then(res => res)
.catch(err => err)
var p12 = new Promise((resolve, reject) => {
throw new Error('报错了');
})
.then(res => res)
.catch(err => err) // 自定义 catch 方法,此时 p12 是一个resolve状态的promise
Promise.all([p11, p12]).then((res) => {
console.log(res) // ["p11 success", Error: 报错了]
}).catch((err) => {
console.log(err) // 不会进入这里
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
如果 rejected 状态的实例没有catch方法,则此时可被 promise.all 的 catch
var p11 = new Promise((resolve, reject) => {
resolve('p11 success');
})
.then(res => res)
.catch(err => err)
var p12 = new Promise((resolve, reject) => {
throw new Error('报错了'); // 没有 catch 方法,此时 p12 是一个rejected 状态的 promise
})
Promise.all([p11, p12]).then((res) => {
console.log(res) // 不会进入这里
}).catch((err) => {
console.log('111', err) // Error: 报错了
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Promise.allSettled()
只要所有传入promise都完成,不管状态是 resolve 还是rejected,都会触发
var p21 = new Promise((resolve, reject) => {
resolve('p21 success');
})
var p22 = new Promise((resolve, reject) => {
reject('p22 error')
})
Promise.allSettled([p21, p22, p23]).then((res) => {
console.log(res) // 输出一个数组
// [
// {
// status: "fulfilled"
// value: "p21 success"
// },
// {
// status: "rejected"
// value: "p22 error"
// }
// ]
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Promise.any()
当第一个成功的 promise resolve返回时触发,如果没有 resolve 状态的 promise,则会报错。
Promise.any() 方法尚未被所有的浏览器完全支持。它当前处于 TC39 第四阶段草案(Stage 4)
var p31 = new Promise((resolve, reject) => {
reject('p31 error');
})
var p32 = new Promise((resolve, reject) => {
setTimeout(resolve, 500, "最终完成");
})
var p33 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, "最快完成");
})
// 传入一个 promise 数组
Promise.any([p31, p32, p33]).then((res) => {
console.log(res) // 最快完成
})
// 传入的 promise 没有resolve 状态
Promise.any([p31]).then((res) => {
console.log(res) // "AggregateError: No Promise in Promise.any was resolved"
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Promise.race()
返回第一个 promise 完成的值,无论是成功还是失败。如果多个 promise 同时返回,则按传入顺序返回第一个。
# 基础用法
var p41 = new Promise((resolve, reject) => {
reject('p41 error')
})
var p42 = new Promise((resolve, reject) => {
resolve('p42 success')
})
var p43 = new Promise((resolve, reject) => {
setTimeout(resolve, 500, "最慢完成");
})
// 返回第一个完成的 promise 值
Promise.race([p41, p42, p43]).then(null, (err) => {
console.log(err) // p41 error
})
// 假设都没有延迟,因为promise实例化时立即执行,所以会按执行顺序,返回第一个的值
Promise.race([p42, p41, p43]).then((res) => {
console.log(res) // p42 success
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 应用场景
可以设置如果指定时间内没有获得结果,就将 Promise 的状态变为reject,否则变为resolve。
var p44 = new Promise((resolve, reject) => {
setTimeout(resolve, 5000, "5s才返回");
})
var p45 = new Promise((resolve, reject) => {
setTimeout(reject, 3000, "3s不返回就error");
})
Promise.race([p44, p45])
.then(console.log)
.catch(console.error); // 3s不返回就error
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 使用注意
Promise.reject()方法的参数,会原封不动地作为reject的理由,变成后续方法的参数
var thenable = {
then(resolve, reject) {
reject('出错了');
}
};
Promise.reject(thenable)
.catch(e => {
console.log(e === thenable) // true => 输出了整个 thenable 对象,而不是 ”出错了“
})
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
- 实现一个promise
- 如何实现 promise.all
- 如何实现 promise.finally
- fetch是Es6的一个api,是一个获取资源的接口,包括跨域。就是一个类似与ajax的api
- 可以使用fetch polyfill兼容
- fetch无论成功与否,都会返回一个promise对象
- fetch核心在于HTTP接口的抽象
关于fetch与jq.ajax不同的地方
- 即便是http响应状态码为400/500,fetch()返回的promise也是resolve,只是resolve的of属性为false。仅当故障或者请求被阻止的时候,才会被标记为reject
- 默认下,fetch不会从服务端发送或接受任何cookies,如果需要,则要设置credentials 选项
// 还有其他自定义参数
myHeaders = new Headers({
"Content-Type": "text/plain",
"Content-Length": content.length.toString(),
"X-Custom-Header": "ProcessThisImmediately",
});
myHeaders.append("h_shop", shopNo);
fetch(url,{}).then(function(response) {
// return 结果,被下一次then调用
return response;
}).then(function(response) {
// response.ok:状态码在200~299都是ok
if(response.ok) {
console.log('成功')
} else {
console.log('网络故障类错误');
}
}).catch(function(error) {
// 捕捉错误
});;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
参考文章:
https://www.jianshu.com/p/d8a901dd72ac