那天我正在学习 Promise,忽然家里打电话过来讲,家里盖房子要钱。我工做这么多年了,从事着别人眼中高薪工做,因而满口答应下来。可是因为我并无钱,因而我跟家里说,等过几天我再打钱过去。我也好乘着这几天想一想办法。数组
首先我找到个人同窗李雷,他如今一个部门经理了,我想应该他应该有钱。我跟他说明了借钱的意向,李雷二话不说就答应借我300,不过同时表示要回家跟老婆商量商量,我说好。此时我想起来答应或者说承诺的英文单词就是 Promise
。承诺的结果是钱,钱是数值(number 类型)。因而我想把我要借钱的这一行为写成一个TypeScript
函数以下:promise
// 向李雷借钱,李雷丢给我一个承诺 function borrowMoneyFromLiLei(): Promise<number> { return new Promise<number>(function(fulfill, reject) { // 李雷跟老婆商量中 }); } 复制代码
此时,我在想李雷老婆会答应给我借300块吗?我不肯定,就像薛定谔的猫。借仍是不借,这是一个问题。而后我发现这也能够写成一个函数。借或者不借用布尔值来表示 (boolean 类型)。函数以下:bash
// 李雷的老婆是否会答应给我借钱? function willLiLeiWifeLendMeMoeny(): Promise<boolean> { return new Promise<boolean>(function(lend, reject) { // 借仍是不借 }); } 复制代码
若是李雷借我钱了,我就转钱给家里,没有,我应该要再去找别人借了。能够用下面的函数描述我此时的处境。markdown
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
方法,也许这个方法能够帮助我表达个人这一决策需求.spa
function borrowMoneyFromOthers() { // 同时向张三,李四,王五借钱,只要有人借我钱了,我就转钱给家里。 Promise.race([ tryBorrowMoneyFromZhangshan(), tryBorrowMoneyFromLisi(), tryBorrowMoneyFromWangwu() ]) .then(transferMoneyToHome) .catch(reasons => { console.warn("没一我的愿意给我借钱,他们理由是:", reasons); }); } 复制代码
我用timeout 模拟一下他们给我答复的,代码以下:code
// 尝试找张三借 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); }); } 复制代码
结果运行以后,控制台输出的是:orm
没一我的愿意给我借钱,他们理由是: 对不起我也没钱ip
看来 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: 不要再买了
复制代码
然而,幻想结束以后,我依然得苦苦思考怎么样筹钱。