04、ES6 Promise

回调与promise

 回调

//回调: 用于请求数据。每次调用都传入一个回调函数

function hui(bb){
    bb && bb();  //判断传进来的bb 是否存在,若存在是否函数,若函数就调用
}
hui(function(){
    console.log(1);

    hui(function(){ //这里面可以调用console.log(1)那一层的内容
        console.log(2);

        hui(function(){//这里面可以调用console.log(2)那一层的内容
            console.log(3);
        });
    });
});
//这样嵌套地调用维护成本高,个人建议两层以上就不要用这种方法了,改用promise

Promise

//promise: 用于请求数据
function hui(){
    return new Promise(bb => { bb(); });
}

hui()
.then(function(){    //每一个Promise都有一个then方法
    console.log(1);
    return hui();    //若下面还有用到then,必须返回Promise实例,而Promise实例就在hui()中
})
.then(function(){  //then里面的function对应的是,hui()里面的bb
    console.log(2);
    return hui();
})
.then(function(){
    console.log(3);     //下面没有then了,就不必返回Promise实例
})

信任问题 

//一般回调
//如调用第三方库,并传入一个回调
function methods(cb){
    //未按照所想预期执行回调
    setTimeout(function(){
        //现在执行一下回调
        cb&&cb();
        //不明情况下又执行了一下回调,最后导致程序出错
        cb&&cb();
    },2000)
}
//Promise
//Promise一旦确认为成功或失败 就不能被更改
function methods(){
    return new Promise(resolve => { 
        setTimeout(function(){
            resolve();    //成功一次只能调用一次Promise里面的回调
            resolve();    //第二次调用是不会成功的
        },2000)
    })
}

 错误处理

 //promise有成功也有失败。

 失败的回调(不传参)

//不传参
//promise失败的情况下的处理
function methods(val){
    return new Promise((resolve,reject) => {
        if(val){ //若val为true,则执行成功做的事
            resolve();
        }else{ //若val为false,则执行失败做的事
            reject();
        }
    });
}

//then(resolve,reject)
//then方法中,第二个回调是失败时做的事
methods(false)
.then(()=>{
    console.log('成功');
},()=>{
    console.log('失败');
})

 失败的回调(传参)

//传参
//promise失败的情况下的处理
function methods(val){
    return new Promise((resolve,reject) => {
        if(val){
            resolve({name:'萱萱',age:18}); //成功时传入的参数,只能传一个参数。若传的是对象,里面可包含多个数据
        }else{
            reject('404');  //失败时传入的参数。同样只能传一个参数
        }
    });
}

methods(false)
.then(success=>{
    console.log(success); //成功时接收的参数
},fail=>{
    console.log(fail);//失败时接收的参数
})

 catch

//捕获错误,并对其进行处理

//catch
//使用catch的实例方法,可以捕获错误

methods(true)
.then(()=>{
    console.log('先成功后失败');
    return methods(false); //若返回了false,后面没有与之对应的回调或catch就会出错
})

.then(()=>{
    console.log('第一个回调是成功执行的,所以这条语句会被跳过');
})

// //方法一
// .then(()=>{  //成功的回调
//     console.log('这里的成功回调也不会被执行');    
// },()=>{  //失败的回调
//     console.log('若前面的错误回调一直没有被执行,那么就会延续到这里执行')
// })

//方法二
.catch(()=>{
    console.log('这条是用来捕获错误用的');
})

finally

//最后执行的内容

//finally
//无论成功或失败都会执行finally
.finally(()=>{
    console.log('最后才会执行的内容');
})

promise的三种状态

//状态的改变不可逆,一旦决议就不能再修改

pending: 进行中

fulfilled:成功

rejected:失败

//一旦从pending变成了fulfilled,或从pending变成了rejected,就不能够更改了 

 Promise.all

//将多个promise实例,包装成一个新的promise实例。

即 Promise.all ([ promise1 , promise2 ] )

1、当promise里面全部决议为成功promise.all才会决议为成功,并将resolve所带的参数,按顺序组成一个数组返回

2、当promise里面有一个决议为失败promise.all就会决议为失败,并将决议失败的rejected所带的参数,按顺序组成一个数组返回

3、当 Promise.all 为空数组的时候,就会决议为成功,即 Promisse.all ([ ])

// Promise.all
function getData1(val){
    return new Promise((resolve,reject)=>{
        if (val) {
            resolve('data1');
        }else{
            reject('data1 error')
        }
    })
}
function getData2(val){
    return new Promise((resolve,reject)=>{
        if (val) {
            resolve('data2');
        }else{
            reject('data2 error')
        }
    })
}
function getData3(val){
    return new Promise((resolve,reject)=>{
        if (val) {
            resolve('data3');
        }else{
            reject('data3 error')
        }
    })
}

let p = Promise.all([getData1(true),getData2(true),getData3(true)]);

p.then(arr=>{
    console.log('当所有promise实例决议为true时,才输出')
    console.log(arr);
},e=>{
    console.log('当某一项为false时,输出某一项的reject信息');
    console.log('若有两项错误信息,则输出最先出现的那个错误信息');
    console.log(e);
})
//当promise.all里为空数组时,决议为true
let p = Promise.all([]);

p.then(arr=>{
    console.log('当promise.all里为空数组时,决议为true')
    console.log(arr);
},e=>{
    console.log(e);
})

 Promise.race

 //在promise的实例中,只要有一个返回成功/失败,那么promise.race就为成功/失败

//若promise.race接收的是空数组,则会永远地挂起

//Promise.race
//在promise的实例中,只要有一个返回成功/失败,那么promise.race就为成功/失败
const promise1 = new Promise(function(resolve, reject) {
    setTimeout(resolve, 500, 'one');
});

const promise2 = new Promise(function(resolve, reject) {
    setTimeout(resolve, 100, 'two');
});

Promise.race([promise1, promise2]).then(function(value) {
  console.log(value);
  // 两个都是成功的,但是promise2反应速度更快,所以这里的就是two
});
// expected output: "two"

Promise.resolve() 与 Promise.reject()

//常用来生成已经被决议为成功或失败的Promise实例

Promise.resolve()传递参数时,有3种情况

第一种,传递普通值

let p1 = new Promise(resolve=>{ //两条语句的效果都一模一样
    resolve('成功');
});
let p2 = Promise.resolve('成功'); //两条语句的效果都一模一样

第二种,传递promise实例

let p = new Promise(resolve=>{
    resolve('好');
})
let pp = Promise.resolve(p); //直接将p的promise实例返回给pp,即 p === pp
pp.then(data=>void console.log(data)); //这里接收的参数是p里面resolve的参数

第三种,传递一个thenable对象

//thenable就是具有then方法的对象
let obj = {
    then(cb){
        console.log('obj里面的then被执行了');
        cb('这里相当于resolve传递参数');
    },
    oth(){
        console.log('其他');
    }
};
//立即执行then方法
Promise.resolve(obj).then(data =>{
    console.log(data);
});

//不管什么值,只要Promise.resolve包一下就成为了promise实例了。

Promise.reject()

//只要决议为失败,会按照原来的原封不动地传递过来

Promise.reject({then() {console.log('并不会解析这条内容,只负责传递');} })
.then(()=>{
    //这里是决议成功的函数,这里用不到
},e=>{
    console.log(e); //这里输出的是then函数本身,不会进行解析
});

 Promise同步与异步

 //promise决议之后,异步地执行后面地事情,异步任务在同步任务之后执行。如then里面就是异步任务。

根据这个特性,可将同步任务转为异步任务

function createAsyncTask(syncTack){
    return Promise.resolve(syncTack).then(syncTack=>{
        syncTack()
    });
}

createAsyncTask(()=>{
    console.log('我变成了异步任务');
    return 1+1;
}).then(res=>{
    console.log(res);
});

console.log('我是同步任务');

猜你喜欢

转载自www.cnblogs.com/mingliangge/p/12620145.html
今日推荐