0%

Promise

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const getApplyQueue = (ownerId, channelId) => {
return new Promise((resolve, reject) => {
let sql = `select * from ApplyQueue where channelId="${channelId}" and ownerId="${ownerId}"order by time`;
db.query(sql, (err, userList) => {
if(userList.length == 0){
return resolve(`null`) // 这里如果不加 return 代码会向下执行
}
console.log(`userList is ${JSON.stringify(userList)}`)
getUserInfoByArray(userList).then((data) => {
resolve(data)
}).catch((err) => {
console.log(`err is ${err}`)
reject(err)
})
})
})
}

Promise resolve和reject的数据都是要在后续的.then()或者.catch()中才能会获取到

1
2
3
4
5
6
7
8
9
10
11
const promise = (data) => {
return new Promise((resolve, reject) => {
if(data == -1){
resolve(1)
}else{
reject(0)
}
})
}

console.log(promise(-1)) //输出Promise { 1 }

promise(-1)执行的结果应该是resolve(1),但是打印出来的并不是1,而是Promise{1},这是经过Promise对象封装过的,他是不等于1的

promise(-1) == 1 //false

所以resolve和reject的数据和直接return还是有不一样的

如果

1
2
return new Promise((resolve, reject) =>{
} )

这样写,那么Promise里的数据只有用resolve()或者reject()才能传到.then()里。

1
2
3
4
5
.then((v) => {
return 123;
}).then(v => {
console.log(v)
})

如果then里的是一个function,那么它return的数据可以直接传到下一个then里。

Promise 的链式写法

1
2
3
4
5
6
7
8
9
10
11
12
runAsync1()
.then(function(data){
console.log(data);
return runAsync2();
})
.then(function(data){
console.log(data);
return runAsync3();
})
.then(function(data){
console.log(data);
});

如果提前把函数用Promise封装好,那么就可以在then里写一个函数然后return那个用Promise封装好的函数,这样下一个then里接收的就是上一个return的Promise函数的resolve

.then()函数其实接收2个参数,第一个是上一个Promise的resolve,第二个就是reject。而.catch()其实是一个类似语法糖的东西,他接收的也是err,这是为了让代码看起来逻辑更加清晰。

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
const fuc = (data) => {
return new Promise((resolve, reject) => {
if(data>5){
resolve(1)
}else{
reject(-1)
}
})
}
fuc(1).then(v => {
console.log(v)
}).catch(err => {
console.log(err)
})
完全等同于
const fuc = (data) => {
return new Promise((resolve, reject) => {
if(data>5){
resolve(1)
}else{
reject(-1)
}
})
}
fuc(1).then(v => {
console.log(v)
}, err => {
console.log(err)
})

不过它还有另外一个作用:在执行resolve的回调(也就是上面then中的第一个参数)时,如果抛出异常了(代码出错了),那么并不会报错卡死js,而是会进到这个catch方法中。也就是说.catch()不仅仅接收上一个Promise的reject或者错误,还接收上一个.then()的错误

1
2
3
4
5
6
7
8
9
10
getNumber()
.then(function(data){
console.log('resolved');
console.log(data);
console.log(somedata); //此处的somedata未定义
})
.catch(function(reason){
console.log('rejected');
console.log(reason);
});
  • Promise.all()是一个遍历Promise对象的方法,他的参数就是装着Promise对象的数组。然后在并发的执行参数里的Promise,最后会依次的把各个Promise resolve的结果返回到最后的then里,依次的装到数组里。如果有其中任何一个 Promise reject 了,那 Promise.all() 返回的将会是空{}.
  • 如果这个promise队列里出现了reject,那么Promise.all()返回的结果会被一个reject而报销(其他正常返回也没用了),所以为此你最好使队列每一个ajax封装一个:
1
2
3
Promise.race(ajax,()=>new Promise(resolve=>{
setTimeout(()=>reslove('timeout'),3000)
}))

这样也可以解决某一个ajax响应时间巨长,导致Promise.all()一直pending的问题