用Promise讲一个悲伤的故事给你听

数据库2025-11-05 04:52:237

那天我正在学习 Promise,悲伤突然家里打电话过来说,家里盖房子要钱。悲伤我工作这么多年了,悲伤从事着别人眼中高薪工作,悲伤于是悲伤满口答应下来。但是悲伤由于我并没有钱,于是悲伤我跟家里说,等过几天我再打钱过去。悲伤我也好乘着这几天想想办法。悲伤

首先我找到我的悲伤同学李雷,他现在一个部门经理了,悲伤我想应该他应该有钱。悲伤我跟他说明了借钱的悲伤意向,李雷二话不说就答应借我300,悲伤不过同时表示要回家跟老婆商量商量,悲伤我说好。此时我想起来答应或者说承诺的英文单词就是 Promise 。承诺的结果是钱,钱是数值(number 类型)。于是我想把我要借钱的这一行为写成一个 TypeScript 函数如下:

// 向李雷借钱,李雷丢给我一个承诺 function borrowMoneyFromLiLei(): Promise<number> {   return new Promise<number>(function(fulfill, reject) {      // 李雷跟老婆商量中   }); } 

此时,我在想李雷老婆会答应给我借300块吗?我不确定,亿华云就像薛定谔的猫。借还是不借,这是一个问题。然后我发现这也可以写成一个函数。借或者不借用布尔值来表示 (boolean 类型)。函数如下:

// 李雷的老婆是否会答应给我借钱? function willLiLeiWifeLendMeMoeny(): Promise<boolean> {   return new Promise<boolean>(function(lend, reject) {     // 借还是不借   }); } 

如果李雷借我钱了,我就转钱给家里,没有,我应该要再去找别人借了。可以用下面的函数描述我此时的处境。

function transferMoneyToHome(money: number) {     // 给家里转钱 } function mySituation(){     borrowMoneyFromLiLei()     .then((money:number) => {         // 如果李雷借我钱了,我就转钱给家里.         transferMoneyToHome(money)     }).catch((reason) => {         // 李雷老婆拒绝借钱给我。 那我应该考虑向其他人借了。         borrowMoneyFromOthers()     }) } 

找其他人借,我能想到就(张三,李四,五五)这三个人了,其他的朋友很少联系,突然说借钱也不好。于是我尝试向他们借钱。用代码表示是这样子的:

function borrowMoneyFromOthers() {   // 我先试着向张三借   tryBorrowMoneyFromZhangshan()     .then(money => {       transferMoneyToHome(money);     })     .catch(reason => {       // 如果张三不借,云服务器并丢给我一个理由       // 试着向李四借       tryBorrowMoneyFromLisi()         .then(money => {           transferMoneyToHome(money);         })         .catch(reason2 => {           // 如果 李四也不肯错           // 再试试向王五借           tryBorrowMoneyFromWangwu()             .then(money => {               transferMoneyToHome(money);             })             .catch(reason => {               // 没有人肯借               throw new Error("我该怎么办呢?");             });         });     }); } 

由于借着钱之后都是向家里转钱,所以上面的代码应该简化一下。简化后如下:

function borrowMoneyFromOthers() {   // 我先试着向张三借   tryBorrowMoneyFromZhangshan()     .then(transferMoneyToHome)     .catch(reason => {       // 如果张三不借,并丢给我一个理由       // 试着向李四借       tryBorrowMoneyFromLisi()         .then(transferMoneyToHome)         .catch(reason2 => {           // 如果 李四也不肯错           // 再试试向王五借           tryBorrowMoneyFromWangwu()             .then(transferMoneyToHome)             .catch(reason => {               // 没有人肯借               throw new Error("我该怎么办呢?");             });         });     }); } 

在上面的思路中,我是一个一个找他们借钱的,一个借不着再找另一个。我为什么不同时找他们借呢?谁借我了,我就转钱给家里。此时我想起了刚学的 Promise.race 方法,也许这个方法可以帮助我表达我的这一决策需求.

function borrowMoneyFromOthers() {   // 同时向张三,李四,王五借钱,只要有人借我钱了,我就转钱给家里。   Promise.race([     tryBorrowMoneyFromZhangshan(),     tryBorrowMoneyFromLisi(),     tryBorrowMoneyFromWangwu()   ])     .then(transferMoneyToHome)     .catch(reasons => {       console.warn("没一个人愿意给我借钱,他们理由是:", reasons);     }); } 

我用timeout 模拟一下他们给我答复的,代码如下:

// 尝试找张三借 function tryBorrowMoneyFromZhangshan(): Promise<number> {   return new Promise(function(fulfill, reject) {     setTimeout(() => {       fulfill(300);     }, 100);   }); } // 尝试找李四借 function tryBorrowMoneyFromLisi(): Promise<number> {   return new Promise(function(fulfill, reject) {     setTimeout(() => {       reject("对不起我也没钱");     }, 50);   }); } // 尝试找王五借 function tryBorrowMoneyFromWangwu(): Promise<number> {   return new Promise(function(fulfill, reject) {     setTimeout(() => {       fulfill(300);     }, 500);   }); } 

结果运行之后,控制台输出的是:

没一个人愿意给我借钱,他们理由是: 对不起我也没钱

看来 Promise.race 适用用来模拟抢答,而不是选择最优解。亿华云计算 比如多人抢答一个问题,第一个抢答之后不论他回答的是否是正确,这个题都过了。

不过没关系。也许我可以自己写一个来叫做 promiseOne 的函数来实现这个功能。代码如下:

/**  * 当其中一个 Promise 兑现时,返回的 Promise 即被兑现  * @param promises Promise<T> 的数组  */ function promiseOne<T>(promises: Promise<T>[]): Promise<T> {   const promiseCount = promises.length;   return new Promise<T>(function(resolve, reject) {     const reasons: any[] = [];     let rejectedCount = 0;     promises.forEach((promise, index) => {       promise.then(resolve).catch(reason => {         reasons[index] = reason;         rejectedCount++;         if (rejectedCount === promiseCount) {           reject(reasons);         }       });     });   }); } 

正当我写完了上面的代码,他们三个给我回话了,说是现在手上也没有那么多钱,但是可以给我借100. 于是我现在需要处理这样的事情,就是当他们三个人把钱都转给我之后我再转给家里。 当他们三个都兑换借我100块钱的承诺时,可以用 Promise.all 来表示,代码如下:

function borrowMoneyFromOthers() {   // 同时向张三,李四,王五借钱, 借到之后,我就转钱给家里。   Promise.all([     tryBorrowMoneyFromZhangshan(),     tryBorrowMoneyFromLisi(),     tryBorrowMoneyFromWangwu()   ])     .then(moneyArray => {       console.info("借到钱啦:", moneyArray);       const totalMoney = moneyArray.reduce((acc, cur) => acc + cur);       transferMoneyToHome(totalMoney);     })     .catch(reasons => {       console.warn("有人不愿意给我借钱,理由是:", reasons);     }); } 

现在有三个人愿意给我借钱了,嗯,也就是说我借到了 300 块。然而这钱用来建房还是杯水车薪。所以我还得想办法。我想我要不要试试用这300块来买一下彩票。如果中了,说不定这事就成了。

function buyLottery(bet: number): Promise<number> {   return new Promise(function(fulfill, resolve) {     // 投注     // 等待开奖     setTimeout(() => {       resolve("很遗憾你没有买中");     }, 100);   }); } function borrowMoneyFromOthers() {   // 同时向张三,李四,王五借钱,    Promise.all([     tryBorrowMoneyFromZhangshan(),     tryBorrowMoneyFromLisi(),     tryBorrowMoneyFromWangwu()   ])     .then(moneyArray => {       console.info("借到钱啦:", moneyArray);       const totalMoney = moneyArray.reduce((acc, cur) => acc + cur);       // 购买彩票       buyLottery(totalMoney)         .then(transferMoneyToHome)         .catch(reason => {           console.log("没中,", reason);         });     })     .catch(reasons => {       console.warn("有人不愿意给我借钱,理由是:", reasons);     }); } 

我知道很大概率我是买不中的,最近世界杯开赛了,我幻想着压注世界杯,而且世界杯场次多,一天好几场,一场买中的盈利还可以投入到下一场。我把我的幻想写成代码,大概就是下面这样。

function betWorldCup() {   // 初始资金 300 块   Promise.resolve(300)     .then(moeny => {       // 投西班牙       return new Promise<number>(function(fulfil, reject) {         setTimeout(() => {           // 假假设 赔率 1.2           fulfil(moeny * 1.2);         }, 100);       });     })     .then(ret => {       // 投英格兰       return ret * 1.2;     })     .then(ret => {       // 投巴西       return new Promise<number>(function(fulfil, reject) {         setTimeout(() => {           fulfil(ret * 1.2);         }, 92);       });     })     .then(ret => {       console.log("现在收益加本金共有: ", ret);     }); } 

我想,如果第一场投失败了,应该再给自己一次机会。于是将代码修改如下:

function betWorldCup() {   // 初始资金 300 块   Promise.resolve(300)     .then(moeny => {       // 投西班牙       return new Promise<number>(function(fulfil, reject) {         setTimeout(() => {           // 假假设 赔率 1.2           // fulfil(moeny * 1.2);           reject("庄家跑跑路了");         }, 100);       });     })     .then(       ret => {         // 投英格兰         return ret * 1.2;       },       reason => {         console.info("第一次投注失败,再给一次机会好不好?, 失败原因: ", reason);         // 再投 300         return 300;       }     )     .then(ret => {       // 投巴西       return new Promise<number>(function(fulfil, reject) {         setTimeout(() => {           fulfil(ret * 1.2);         }, 92);       });     })     .then(ret => {       console.log("现在收益加本金共有: ", ret);       throw new Error("不要再买了");     })     .then(ret => {       console.info("准备再买吗?");     })     .catch(reason => {       console.log("出错了:", reason);     }); } 

此时如下运行上面的函数会得到如下输出:

第一次投注失败,再给一次机会好不好?, 失败原因: 庄家跑跑路了 现在收益加本金共有: 360 出错了: Error: 不要再买了

然而,幻想结束之后,我依然得苦苦思考怎么样筹钱。

本文地址:http://www.bzve.cn/html/578a8199340.html
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

全站热门

电脑远程连接出现证书错误的解决方法(如何处理电脑远程连接中的证书错误问题)

派拓网络IoT/OT安全服务即将落地中国,为企业提供全方位安全保障​

为何1/3企业安全事件源头没法追溯,审视网络安全管理的六大漏洞

SQL ON MongoDB实现原理

微星H170ProVD的性能与特点(全面升级的硬件配置,带给你更顺畅的使用体验)

有了 ReentrantReadWriteLock 读写锁,为何还要引入StampedLock?

首席信息安全官需要应对的十大网络安全挑战

从库延迟案例分析,你学到了什么

友情链接

滇ICP备2023006006号-39