Promise用法

1. 引入原因

    js(nodejs)的耗时请求(如sql和file)都是异步返回。如果调用嵌套太多,则会造成“地狱回调”如下:

sayhello("a", function(err){
    sayhello("b", function(err){
        sayhello("c", function(err){
            sayhello("d", function(err){
                sayhello("e", function(err){
                    console.log("end");
                });    
            });
        });
    });
});

  js想通过一种方案使得以上问题得以解决,得到如下的调用样式。

sayhello("a")
.then(value=>
    {
        sayhello("b");
    })
.then(value=>
    {
        sayhello("c");
    })
.then(value=>
    {
        sayhello("d");
    })
.then(value=>
    {
        sayhello("e");
    })
.then(value=>
    {
        sayhello("end");
    });

 

2. 基本用法

    Promise的构造函数的参数接受2个参数,都是函数。一个是resolve一个是reject。resolve函数将promise的状态职位fulfilled,reject将promise的状态置为rejected。

    这两个函数的具体实现实在then中。如下:

console.log("1111 ");
new Promise((resolve,reject)=>{
    setTimeout(() => {
        if(true)
            resolve("3333 resolved")
        else
            reject("3333 rejected");
        console.log("2222");//此处的2222,在3333world之前输出。
    }, 2000);
})
.then(value=>{
    console.log(value+':resolved')
},value=>{
  console.log(value+":rejected");
});

  

3. 链式调用(返回的是个promise类型)。then中的resolve函数是直接返回的一个非promise的类型,那么这个返回值会作为下一个then的输入参数。

const p = new Promise(function(resolve,reject){
  resolve(1);
}).then(function(value){ // 第一个then // 1
  console.log(value);
  return value * 2;
}).then(function(value){ // 第二个then // 2
  console.log(value);
}).then(function(value){ // 第三个then // undefined
  console.log(value);
  return Promise.resolve('resolve'); 
}).then(function(value){ // 第四个then // resolve,value是个string类型
  console.log(value);
  return Promise.reject('reject'); 
}).then(function(value){ // 第五个then //reject:reject,value是个string类型
  console.log('resolve:' + value);
}, function(err) {
  console.log('reject:' + err);
});

  

3. 关于2个参数。
    then或者promise的构造函数中都可以使用两个参数,resolve函数是必须的,reject函数是可选的。一般不用reject函数,对于错误的处理直接用catch比较简便。catch的用法参考下面。
 
4.then返回一个promise。
   这是promise解决的最重要的“地狱回调”的问题。连环调用querySQL中,用此方法可以使代码可读性增加。返回promise实例,会使得之前的promise被取代。相当于下一个then前新建了一个promise实例。
new Promise( resolve => {
    setTimeout( () => {//等效于读数据库场景
        resolve('hello');//直接运行
    }, 2000);
})
.then( value => {
    console.log(value);
    return new Promise( resolve => {
        setTimeout( () => {
            resolve('world');
            console.log("---")//---先于world world 输出
        }, 2000);
    });
})
.then( value => {
    console.log( value + ' world');
});

  

5. 一个实例(参考慕课网)
console.log('here we go');
new Promise(resolve => {
    setTimeout( () => {
        resolve('hello');
    }, 2000);
})
    .then( value => {
        console.log(value);
        console.log('everyone');
        (function () {
            return new Promise(resolve => {
                console.log("---")
                setTimeout(() => {
                    console.log('Mr.Laurence');
                    resolve('Merry Xmas');//这里不输出,因为这个promise没有返回,所以他跟下面的then无关。
                }, 2000);
            });
        }());
        return false;
    })
    .then( value => {
        console.log(value + ' world');
    });

  输出为

here we go
hello
everyone
---
false world
Mr.Laurence
 
6. catch用法。一般简易使用catch来捕获reject函数,不建议使用promise或者then的第二个函数参数。如下:
new Promise( (resolve,reject) => {
    setTimeout( () => {
        console.log("111")
        if(true)    {
            resolve("success");
        }
        else {
            reject("error");//如果执行了reject,则会直接跳到最后一个catch
        }
    }, 200);
})
.then( value => {
    console.log( "222" + value);
    new Promise( (resolve,reject) => {
        setTimeout( () => {
            console.log("333")
            if(true)    {
                resolve("success");
            }
            else {
                reject("error");
            }
        }, 200);
    })    
})
.catch( error => {
    console.log( 'My Error:', error);
});

  

7. catch后面可以继续then,因为catch也会返回一个promise,将catch理解为reject函数即可。

new Promise(resolve => {
    setTimeout(() => {
        resolve();
        //throw new Error('test error');//这里不能调用throw,这里只能用reject函数
    }, 1000);
})
.then( () => {
    console.log('start');
    throw new Error('test error');
})
.catch( err => {
    console.log('I catch:', err.message);
    // 下面这一行的注释将引发不同的走向
    // throw new Error('another error');
})
.then( () => {
    console.log('arrive here');
})
.then( () => {
    console.log('... and here');
})
.catch( err => {
    console.log('No, I catch:', err);
});

 

8.promise.all([])

原文地址:https://www.cnblogs.com/dongfangchun/p/11414406.html