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

首先我找到我的同学李雷,他现在一个部门经理了,我想应该他应该有钱。我跟他说明了借钱的意向,李雷二话不说就答应借我300,不过同时表示要回家跟老婆商量商量,我说好。此时我想起来答应或者说承诺的英文单词就是 Promise 。承诺的结果是钱,钱是数值(number 类型)。于是我想把我要借钱的这一行为写成一个 TypeScript 函数如下:
- // 向李雷借钱,李雷丢给我一个承诺
 - function borrowMoneyFromLiLei(): Promise
 { - return new Promise
 (function(fulfill, reject) { - // 李雷跟老婆商量中
 - });
 - }
 
此时,我在想李雷老婆会答应给我借300块吗?我不确定,就像薛定谔的猫。借还是不借,这是一个问题。然后我发现这也可以写成一个函数。借或者不借用布尔值来表示 (boolean 类型)。函数如下:
- // 李雷的老婆是否会答应给我借钱?
 - function willLiLeiWifeLendMeMoeny(): Promise
 { - return new Promise
 (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
 { - return new Promise(function(fulfill, reject) {
 - setTimeout(() => {
 - fulfill(300);
 - }, 100);
 - });
 - }
 - // 尝试找李四借
 - function tryBorrowMoneyFromLisi(): Promise
 { - return new Promise(function(fulfill, reject) {
 - setTimeout(() => {
 - reject("对不起我也没钱");
 - }, 50);
 - });
 - }
 - // 尝试找王五借
 - function tryBorrowMoneyFromWangwu(): Promise
 { - return new Promise(function(fulfill, reject) {
 - setTimeout(() => {
 - fulfill(300);
 - }, 500);
 - });
 - }
 
结果运行之后,控制台输出的是:
没一个人愿意给我借钱,他们理由是: 对不起我也没钱
看来 Promise.race 适用用来模拟抢答,而不是选择最优解。 比如多人抢答一个问题,第一个抢答之后不论他回答的是否是正确,这个题都过了。
不过没关系。也许我可以自己写一个来叫做 promiseOne 的函数来实现这个功能。代码如下:
- /**
 - * 当其中一个 Promise 兑现时,返回的 Promise 即被兑现
 - * @param promises Promise
 的数组 - */
 - function promiseOne
 (promises: Promise []): Promise { - const promiseCount = promises.length;
 - return new Promise
 (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
 { - 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
 (function(fulfil, reject) { - setTimeout(() => {
 - // 假假设 赔率 1.2
 - fulfil(moeny * 1.2);
 - }, 100);
 - });
 - })
 - .then(ret => {
 - // 投英格兰
 - return ret * 1.2;
 - })
 - .then(ret => {
 - // 投巴西
 - return new Promise
 (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
 (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
 (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);
 - });
 - }
 
此时如下运行上面的函数会得到如下输出:
然而,幻想结束之后,我依然得苦苦思考怎么样筹钱。
                本文名称:用Promise讲一个悲伤的故事给你听
                
                分享地址:http://www.csdahua.cn/qtweb/news14/467364.html
            
网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网