一、promise深入
-
若在executor里面抛出错误,promise状态会直接更改为reject let promise = new Promise(function(resolve,reject){
resolve(a);
})
promise.then((val)=>{
console.log('resolve: '+val)
},(reason)=>{
console.log('reject: '+reason)
})
-
then的简写 至少有一个参数,不指定用null占位 promise.then(null,(reason)=>{
console.log('reject: '+reason)
});
promise.catch(function(reason){
console.log('reject: '+reason)
})
-
catch
-
基本使用 也可以捕获异常 let promise = new Promise(function(resolve,reject){
resolve(a);
})
promise.catch(function(reason){
console.log(reason)
});
-
语义化写法 当需要捕获异常的时候,推荐使用第二种写法 promise.then(function(){
},function(){
});
promise
.then(function(){
})
catch(function(){
})
-
特性
- 冒泡的特性
- 状态固化之后,无法捕获异常
- 链式调用 then() 的时候,如果什么参数都不传会被直接忽略
let promise = new Promise(function(resolve,reject){
resolve(a);
})
promise.then(function(val){
console.log(val);
}).then().then().catch(function(err){
console.log(err);
})
-
promise固化 如果promise状态发生变化,就意味着状态不会再发生改变 let promise = new Promise(function(resolve,reject){
resolve('ok');
console.log(a);
})
promise.then((val)=>{
console.log(val);
}).catch((err)=>{
console.log(err);
});
-
状态依赖 每一个promise代表的是一个异步操作,每个异步操作都有相应的状态,那么在有多个promise嵌套的情况下,状态又是怎样传递的呢? 当executor的resolve、reject的参数是另一个promise的时候,那么当前promise的状态,就取决于另一个promise的状态 let p1 = new Promise((resolve,reject)=>{
setTimeout(function(){
reject(new Error('fail'));
},3000);
});
let p2 = new Promise((resolve,reject)=>{
setTimeout(function(){
resolve(p1);
},1000);
});
p2.then(result=>console.log(result))
.catch(err=>console.log(err));
当前p2的状态依赖于p1,就会导致p2自己的状态无效,它的状态取决于p1的状态
-
resolve/reject不会终止executor执行 const p1 = new Promise((resolve,reject)=>{
reject(new Error());
console.log(2);
});
p1.then(res=>console.log(res))
.catch(err=>console.log(err));
console.log(3);
-
race/all管理异步的关系 promise通过race、all管理异步之间的关系
-
all 批量处理多个异步操作,返回值是promise对象 参数是具有iterator接口的对象(数组),里面是相应的promise 只有所有promise状态为成功情况下,才会触发成功回调 成功回调参数是一个数组,其顺序与iterable里promise顺序一致 const fs = require('fs');
let promise1 = new Promise((resolve,reject)=>{
fs.readFile('./name.txt','utf-8',function(err,data){
if(err){
console.log(err);
}
resolve(data);
});
});
let promise2 = new Promise((resolve,reject)=>{
fs.readFile('./number.txt','utf-8',function(err,data){
if(err){
console.log(err);
}
resolve(data);
});
});
let promise3 = new Promise((resolve,reject)=>{
fs.readFile('./score.txt','utf-8',function(err,data){
if(err){
console.log(err);
}
resolve(data);
});
});
const p = Promise.all([promise1,promise2,promise3]);
p.then(res=>console.log(res));
只要有一个promise状态为失败,就会触发失败回调 如果全部promise状态都为失败,则只触发iterable里第一个promise状态为失败的回调,其余直接忽略 let promise1 = new Promise((resolve,reject)=>{
setTimeout(function(){
reject('promise1: 1000ms')
},1000)
})
let promise2 = new Promise((resolve,reject)=>{
setTimeout(function(){
reject('promise2: 2000ms')
},2000)
})
let promise3 = new Promise((resolve,reject)=>{
setTimeout(function(){
reject('promise3: 3000ms')
},3000)
})
let p = Promise.all([promise1,promise2,promise3]);
p.then(res=>console.log(res)
).catch((error)=>{
console.log(error);
})
-
race 批量处理多个异步操作,返回值是promise对象 任意一个promise状态为成功或失败,就会触发相应的回调,其余直接忽略 let promise1 = new Promise((resolve,reject)=>{
setTimeout(function(){
reject('promise1: 1000ms');
},1000)
})
let promise2 = new Promise((resolve,reject)=>{
setTimeout(function(){
reject('promise2: 2000ms');
},2000)
})
let promise3 = new Promise((resolve,reject)=>{
setTimeout(function(){
reject('promise3: 3000ms');
},3000)
});
let p = Promise.race([promise1,promise2,promise3]);
p.then(res=>console.log(res)
).catch((error)=>{
console.log(error);
});
-
构造器上的resolve/reject
-
thenable 绑定了then方法的对象就是thenable,用于转换成promise对象 -
resolve —— 转换成功promise对象 返回一个promise对象,当前promise的状态取决于resolve的参数
-
是一个thenable let obj = {
then:function(resolve,reject){
resolve(42);
}
}
let p1 = Promise.resolve(obj);
p1.then(function(value){
console.log(value);
});
-
字符串 let p1 = Promise.resolve('hello');
p1.then(res=>{
console.log(res)
});
-
没有参数 let p1 = Promise.resolve();
p1.then(res=>{
console.log(res)
});
-
reject —— 转换失败promise对象 返回一个promise对象,当前promise的状态取决于resolve的参数
-
thenable(不要用) let obj = {
then: function(resolve, reject) {
reject(new Error('hello'));
}
}
let p1 = Promise.reject(obj);
p1.then(null, function(value) {
console.log(value);
});
-
字符串 let p1 = Promise.reject('hello');
p1.then(null,res=>{
console.log(res)
});
-
不传参 let p1 = Promise.reject();
p1.then(null,res=>{
console.log(res)
});
-
函数Promise化 将异步函数用promise包装一遍 const fs = require('fs');
function readFile(path){
return new Promise((resolve,reject)=>{
fs.readFile(path,'utf-8',(err,data)=>{
if(data){
resolve(data);
}
})
})
}
readFile('./name.txt')
.then(data => readFile(data))
.then(data => readFile(data))
.then(data => console.log(data));
二、promisify
-
promisify概念 能够将所有函数promise化的方法 -
promisify实现(node) const fs = require('fs');
function promisify(func){
return function(...arg){
return new Promise((resolve,reject)=>{
func(...arg,(err,data)=>{
if(err){
reject(err);
}else{
resolve(data)
}
})
})
}
}
let readFile = promisify(fs.readFile);
readFile('./name.txt','utf-8')
.then(data=>readFile(data,'utf-8'))
.then(data=>readFile(data,'utf-8'))
.then(data=>console.log(data));
-
node工具函数中也提供了promisify const util = require('util');
let readFile = util.promisify(fs.readFile);
readFile('./name.txt','utf-8')
.then(data=>readFile(data,'utf-8'))
.then(data=>readFile(data,'utf-8'))
.then(data=>console.log(data));
-
优化node提供的promisify 把fs上的所有方法转成promisify方法 const fs = require('fs');
const util = require('util');
let readFile = util.promisify(fs.readFile);
let readdir = util.promisify(fs.readdir);
let writeFile = util.promisify(fs.writeFile);
function promisify(func){
return function(...arg){
return new Promise((resolve,reject)=>{
func(...arg,(err,data)=>{
if(err){
reject(err);
}else{
resolve(data)
}
})
})
}
}
function promisifyAll(obj){
for(let [key,fn] of Object.entries(obj)){
if(typeof fn === 'function' ){
obj[key+'Async'] = promisify(fn);
}
}
}
promisifyAll(fs)
fs.readFileAsync('./name.txt','utf-8')
.then(data=>readFileAsync(data,'utf-8'))
.then(data=>readFileAsync(data,'utf-8'))
.then(data=>console.log(data));
|