promise基础知识(二)

2022-10-30 14:35:19

一、串联Promise

我们可以将promise串联起来实现更复杂的异步特性的方法。
每次调用then()或者catch()时都会创建并返回另一个promise,只有当第一个promise完成或被拒绝后,第二个才会被解决。下面是一个例子:

let p1 = new Promise(function(resolve,reject){
    resolve(42);
})

p1.then(function(value){
    console.log(value);
}).then(function(){
    console.log("Finished");
});

实现的结果为:
在这里插入图片描述
调用p1.then()之后返回第二个promise,紧接着调用它的then()方法,只有当第一个被解决之后才会调用第二个

1、捕获错误

我们可能在完成处理程序或者拒绝处理程序中发生错误,promise链可以用来捕获这些错误,例如:

let p1 = new Promise(function(resolve,reject){
    resolve(42);
})

p1.then(function(value){
    throw new Error("Boom");
}).catch(function(error){
    console.log(error.message);
});

输出结果为:
在这里插入图片描述
p1的完成处理程序抛出了一个错误,链式调用第二个promise的catch()方法之后,可以通过它的拒绝处理程序来接收这个错误,如果拒绝处理程序抛出错误,我们以相同的方式接收错误。例如:

let p1 = new Promise(function(resolve,reject){
    throw new Error("Explosoin!")
})

p1.catch(function(error){
    console.log(error.message);
    throw new Error("Boom");
}).catch(function(error){
    console.log(error.message);
});

结果如下:
在这里插入图片描述
此处的执行器抛出错误并触发promise p1的拒绝处理程序,这个处理程序又抛出一个错误,并且被第二个promise的拒绝处理程序捕获.。

2、promise链的返回值

promise链的另一个重要的特性是可以给下游promise传递数据,下面是两个例子,无论是完成处理程序还是拒绝处理程序都可以实现:

let p1 = new Promise(function(resolve,reject){
    resolve(42);
});

p1.then(function(value){
    console.log(value);      //42
    return value+1;
}).then(function(value){
    console.log(value);      //43
});

拒绝处理程序的例子:
let p1 = new Promise(function(resolve,reject){
    reject(42);
});
p1.catch(function(value){
    console.log(value);   //42
    return value+1;
}).then(function(value){
    console.log(value);    //43
});
3、在promise链中返回promise

在promise间可以通过完成和拒绝处理程序中返回的原始值来传递数据,如果返回的是对象,则会额外增加一个步骤,请看这个实例:

let p1 = new Promise(function(resolve,reject){
    resolve(42);
});

let p1 = new Promise(function(resolve,reject){
    resolve(43);
});
//第一个处理完成程序
p1.then(function(value){
    console.log(value);   //42
    return p2;
}).then(function(value){
    //第二个处理完成程序
    console.log(value);    //43
});

与下面是等价的:::

let p1 = new Promise(function(resolve,reject){
    resolve(42);
});
let p2 = new Promise(function(resolve,reject){
    resolve(43);
});
//第一个处理完成程序
let p3 = p1.then(function(value){
    console.log(value);   //42
    return p2;
});
p3.then(function(value){
    //第二个处理完成程序
    console.log(value);    //43
});

此处第二个完成处理程序被添加到p3并不是p2,如果p2被拒绝的话,那么第二个处理程序就永远不会被调用,例如:

let p1 = new Promise(function(resolve,reject){
    resolve(42);
});

let p2 = new Promise(function(resolve,reject){
    reject(43);
});
//第一个处理完成程序
p1.then(function(value){
    console.log(value);   //42
    return p2;
}).then(function(value){
    //第二个处理完成程序
    console.log(value);    //从未调用
});

但是我们还是可以通过添加拒绝处理程序来实现:

let p1 = new Promise(function(resolve,reject){
    resolve(42);
});

let p2 = new Promise(function(resolve,reject){
    reject(43);
});
//第一个处理完成程序
p1.then(function(value){
    console.log(value);                     //42
    return p2;
})catch(function(value){
    //第二个处理完成程序
    console.log(value);                     //43
});

p2被拒绝后,拒绝处理程序被调用并且传入p2的拒绝值43.

在完成或拒绝处理程序中返回thenable对象不会改变promise执行器的执行器执行时机,先定义的promise的执行器先执行,后定义的后执行,以此类推。

二、自promise继承

promise与其他内建类型一样,也可以作为基类派生其他类,所以你可以定义自己的promise变量来拓展内建promise模型。下面是一个例子:

class mypromise extends Promise{
    //使用默认的构造函数
    success(resolve,reject){
        return this.then(resolve,reject);
    }
    failure(reject){
        return this.catch(reject);
    }
}
let promise = new mypromise(function(resolve,reject){
    resolve(42);
});
promise.success(function(value){ 
    console.log(value);               //42
}).failure(function(value){
    console.log(value);
});

因为静态的方法会被继承,所以派生的mypromise也拥有mypromise.then()、mypromise.catch()、mypromise.all()、mypromise.race()方法,后两种与内建一致,前两者稍有不同,如果想要了解更多,可以查阅资料。

三、小结

Promise I的设计目标是改进 Javascrip中的异步编程,它能够让你更好地掌控并组合多个同步操作,比事件系统和回调更实用。 Promise s编排的任务会被添加到 Javascript引擎任务队列并在未来执行,还有一个任务队列用于跟踪Promise的完成处理程序和拒绝处理程序并确保正确执行。
Promise有3个状态:进行中( pending)、已完成( fulfilled)和已Promise I的起始状态是进行中,执行成功会变为已完成,失败则变为已拒绝,在后两种情况下你都可以添加处理程序,以便当 Promise被解决( settled)时做出相应操作,通过 theno方法可以添加完成处理程序或拒绝处理程序,通过catch方法只能添加拒绝处理程序有多种方法可将 Promise链接在一起并在它们之间传递信息,每次调用then()方法会创建并返回一个新的 Promise,它会随前面 Promise被解决而解决这样的链条可用于触发一系列同步事件的响应,也可通过 Promise. race0)方法和 Promise,a()方法来监控多个 Promise的进程并做出相应响应。

参考文档:深入理解ES6

  • 作者:洳娅
  • 原文链接:https://blog.csdn.net/qq_39897978/article/details/89915140
    更新时间:2022-10-30 14:35:19