35 – Promises:链式、错误处理和运算符

2022-12-18 0 384

35 – Promises:链式、错误处理和运算符

书名:

https://dev.to/bhagatparwinder/promises-chaining-error-handling-operators-3ccb

上首诗详尽的如是说了甚么是 promise 和怎样建立、 resolve 和 reject。

这一场,他们将探讨 promise 中的拉艾操作方式和consequences和需用的操作方式符。

拉艾

反弹表达式最明显的优点众所周知是当他们相连它时逐步形成的冗余内部结构,在 then 的协助下,他们能建立两个更易写作、认知和增容的细长内部结构。

假定他们有两个 waitForMe 的表达式回到 promise,那个表达式等候 2 秒前会回到你好友的英文名字。

constwaitForMe =function(name) { return new Promise((resolve, reject) => { setTimeout(() => { returnresolve(name); },2000); }); } waitForMe(“Parwinder”) .then((data) => { console.log(data); // Outputs/yells “Parwinder” after 2 second });

假定你有很多懒惰的好友,因为你很着急想都给他们打电话。他们能两个个的给他们打电话(拉艾操作方式)。

waitForMe(“Parwinder”) .then((data) => { console.log(data); // waits 2 seconds and outputs “Parwinder” return waitForMe(“Lauren”); }) .then((data) => { console.log(data); // waits another 2 seconds and outputs “Lauren” returnwaitForMe(“Robert”); }) .then((data) => { console.log(data); // waits another 2 seconds and outputs “Robert” return waitForMe(“Eliu”); }) .then((data) => { console.log(data); // waits another 2 seconds andoutputs“Eliu” })

你会看到他们是怎样用拉艾调用英文名字的和控制台间隔 2 秒打印出它,每两个 then 操作方式符会回到两个 promise 然后和其他的 then 链起来,同时保持代码内部结构的扁平。

consequences

在 promise 的拉艾中有两种方法能处理错误,要么在 then 块中传入consequences器或者使用 catch 操作方式符。他们已经在前一首诗中探讨了第一种方法。

const myPromise =new Promise((resolve, reject) => { setTimeout(() => { reject(“an error has occurred”); }, 2000) }); myPromise.then((response) => { console.log(response); }, (error) => { console.log(error);// an error has occurred });

在上面的例子中,then 包含两个反弹,第两个是成功的处理器,第二个是consequences器。使用这两个处理器是完全没有问题的同时在多数情况下工作良好。它也有某些优点:

如果成功处理器中产生了错误,你将无法捕获或处理它;如果你像上面的拉艾例子一样使用拉艾调用,你需要在每个 then 块中添加consequences器。

为了解决这些优点,他们使用 catch 操作符。

const myPromise = new Promise((resolve, reject) => { setTimeout(() => { reject(“an error has occurred”); }, 2000) }); myPromise.then((response) => { console.log(response); }).catch((error) => { console.log(error); // an error has occured });

在 promise 的拉艾调用中,他们能这样使用 catch 操作方式符:

const waitForMe = function (name) {return new Promise((resolve, reject) => { if (name === “Robert”) { returnreject(“Robert is always on time”); } else { setTimeout(() => { return resolve(name); }, 2000); } }); } waitForMe(“Parwinder”) .then((data) => { console.log(data); // wait 2 second and log “Parwinder” return waitForMe(“Lauren”); }) .then((data) => { console.log(data); // wait 2more secondsand log “Lauren” return waitForMe(“Robert”); // this will result in promise rejection }) .then((data) => { console.log(data); // this never gets executed return waitForMe(“Eliu”); }) .then((data) => { console.log(data); // this never gets executed }) .catch((error) => { console.log(error); // Robert isalwayson time })

记住在 promise 的拉艾调用中一旦有两个产生错误后续的链将会被终止。这也是为甚么最后两个打印没有执行。

catch 操作方式符并不总是必须添加到最后,它能添加到拉艾的中间然后能捕获到它那个位置之前的错误。

const waitForMe = function (name) { return new Promise((resolve, reject) => { if(name ===“Robert”) { return reject(“Robert is always on time”); } else { setTimeout(() => { returnresolve(name); },2000); } }); } waitForMe(“Parwinder”) .then((data) => { console.log(data);// wait 2 second and log “Parwinder” return waitForMe(“Lauren”); }) .then((data) => { console.log(data); // wait 2 more seconds and log “Lauren” return waitForMe(“Robert”); // this will result in promise rejection }) .catch((error) => { // catches the promise rejection console.log(error); // Robert is always on time return waitForMe(“Eliu”); // continues the chain }) .then((data) => { console.log(data);// Eliu })

注意: 为甚么不一直使用 catch 而忽略 then 中的consequences器呢?

我上面提到过 then 的劣势:

需要为每两个 then 添加两个consequences器。

有时候你可能需要在拉艾 then 的consequences器中有不同的consequences方式,基于这一点,then 中独立的consequences器可能会更有优势。

操作方式符

promise 上有两个重要的操作方式符,它分别适应特定的场景:Promise.all 和 Promise.race。

Promise.all

当你在两个异步操作方式后执行另两个(串行),promise 的拉艾调用很顺手。经常,你需要多个异步操作方式并行执行而不是等两个执行完成后再执行。另外,你的操作依赖所有的异步操作方式的完成情况。

Promise.all 使他们能同时执行多个异步操作方式,但依旧需要等到它都完成 了才执行反弹。

const waitForMe = function (name) { return new Promise((resolve, reject) => { setTimeout(() => { return resolve(name); }, 2000); }); }const firstPromise = waitForMe(“Parwinder”); const secondPromise = waitForMe(“Lauren”); constthirdPromise = waitForMe(“Robert”); const fourthPromise = waitForMe(“Eliu”); Promise.all([firstPromise, secondPromise, thirdPromise, fourthPromise]) .then((data) => { console.log(data); // [ Parwinder, Lauren, Robert, Eliu ] });

上面的例子同时执行了 promise,等到它都回到 name 就会输出两个结果的数组。这种方式执行耗费 2 秒,拉艾的形式则耗费 8 秒来输出四个英文名字。

数组中输出顺序是严格与输入 Promise.all 中的顺序是一致的。

注意: Promise.all 中即使有两个错误产生,整个结果都会失败。

const waitForMe = function (name) { return new Promise((resolve, reject) => { if (name === “Robert”) { return reject(“Robert is always on time”); }else { setTimeout(() => { return resolve(name); }, 2000); } }); } constfirstPromise = waitForMe(“Parwinder”); const secondPromise = waitForMe(“Lauren”); const thirdPromise = waitForMe(“Robert”); const fourthPromise = waitForMe(“Eliu”); Promise.all([firstPromise, secondPromise, thirdPromise, fourthPromise]) .then((data) => { console.log(data); }) .catch((error) => { console.log(error);// Robert is always on time })

它会忽略其他成功的 promise,若有多个错误它会回到输入 Promise.all 中数组的第两个发生错误的 promise。

constwaitForMe =function (name) { return new Promise((resolve, reject) => { if (name === “Robert”) { return reject(“Robert is always on time”); } else if (name === “Lauren”) { return reject(“Lauren is always on time”); }else { setTimeout(() => { return resolve(name); }, 2000); } }); } constfirstPromise = waitForMe(“Parwinder”); const secondPromise = waitForMe(“Lauren”); const thirdPromise = waitForMe(“Robert”); const fourthPromise = waitForMe(“Eliu”); Promise.all([firstPromise, secondPromise, thirdPromise, fourthPromise]) .then((data) => { console.log(data); }) .catch((error) => { console.log(error);// Lauren is always on time })

Promise.race

Promise.race 处理两个特殊的情形,当你需要同时执行多个异步操作方式,但不需要等到它全部完成。相反,你想当第两个 promise 完成后尽快执行反弹。

const waitForMe = function (name, time) { return new Promise((resolve, reject) => { setTimeout(() => { return resolve(name); }, time); }); } constfirstPromise = waitForMe(“Parwinder”, 4000); const secondPromise = waitForMe(“Lauren”, 3000); const thirdPromise = waitForMe(“Robert”, 7000); const fourthPromise = waitForMe(“Eliu”, 5000); Promise.race([firstPromise, secondPromise, thirdPromise, fourthPromise]) .then((data) => { console.log(data); // Lauren }) .catch((error) => { console.log(error); })

我为 setTimeout 添加了两个参数,跟着每两个英文名字我传入了不同的时间,”Lauren” 只有 3 秒钟所以她永远会赢得”比赛”,然后打印出她的名字。

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务