Can Anyone In The NL Central Stop The Cubs

Based on projected wins or over/under win totals. Data gathered on March 16, 2017.Sources: Baseball Prospectus, Fangraphs, Clay Davenport, Las Vegas Review-Journal 5Cincinnati Reds7470747172.1 neil (Neil Paine, FiveThirtyEight senior sportswriter): So let’s get started with the elephant in the room of this division: The Cubs are once again huge favorites — 88 percent to win the division, according to FanGraphs. What can we say about them that hasn’t already been said ad nauseam during their World Series run last year?craigjedwards: Just replace “Will they end the drought?” with “Will they repeat?”neil: Or maybe “Will they form a dynasty?”natesilver: I would say that 88 percent to win the division intuitively sounds very high. We had them at 56 percent last year in a similar-ish situation.craigjedwards: 88 percent is high. Although last season both the Cardinals and Pirates appeared to have better teams than they do this season.natesilver: But bigger picture … What is there to say except that it’s been a while since we had a baseball team that was set up for this sort of long-term success?craigjedwards: They basically have the same team back, with few guys to worry about suffering precipitous aging declines, plus Jason Heyward possibly not being as bad as he was last season.natesilver: Let’s not forget that they’re also up one Kyle Schwarber this year (although he won’t help on defense).craigjedwards: The only question is the pitching rotation. In 2015 and 2016, they had all their top guys healthy and pitching well. It would take a major disaster in the rotation, but if they don’t meet expectations, that is where it is likely to come from.neil: Right — did that pitching performance last year contain a lot of luck in addition to skill? They allowed an MLB-low .255 batting average on balls in play (BABIP), 27 points lower than any other team.craigjedwards: Luck on the pitcher’s part? Yes, but that luck comes in the form of a fantastic defense. That is luck for the pitchers, not luck for the Cubs. That said, their BABIP is going to go up, since even guys who showed no prior ability to suppress contact did so last season. But even if they aren’t quite as good, it is reasonable to expect a low BABIP again because of that defense.neil: Another note on that pitching staff is that they were the oldest in the majors last year. And yet, only two other teams have relied on their starting rotation for more innings over the past two seasons than Chicago has. Is that a red flag? Or does it even matter?natesilver: Pitcher aging is weird. It’s kind of like: you’re good, until you’re suddenly not.craigjedwards: John Lackey is probably the most worrisome, because he is getting to an age where he could all of a sudden be finished.natesilver: I think the question is what sort of reinforcements they could bring in if Lackey turned into a pumpkin, for instance.craigjedwards: Jon Lester has also defied the aging curve over the past two seasons, and his velocity is down this spring, so that is a concern as well. Plus, it will be interesting to see how Willson Contreras plays out defensively at catcher, as he’ll be replacing David Ross as Lester’s personal catcher.natesilver: But let’s keep in mind that the Cubs are not only smart, but rich — so they’re a good candidate to bring a pitcher in at the trade deadline if they need one.craigjedwards: Chicago’s minor league system isn’t as deep as it was, since its young stars are already in the majors (or were traded last year), but there are a few high-end prospects they could move if they needed to.neil: I might also be grasping to find holes in the Cubs just to have something to debate. This staff could probably lose half its value from last year and they’d still win 90+ games.Chicago also seemed to effectively plug the roster holes that opened over the offseason: Lose Dexter Fowler? Here’s Jon Jay. Lose Aroldis Chapman? Here’s Wade Davis. Cut Jason Hammel loose? Here’s Brett Anderson. Like Nate said, they’re getting Schwarber back, too. And I guess it would be hard for Heyward to be worse.craigjedwards: Heyward has to be better than he was last season. Even if he never hits like he did before he got to the Cubs, an average-hitting Heyward with his defense and baserunning is a four-win player.natesilver: But we’re talking about a very high bar that the Cubs will have to clear to keep pace with their performance from last year. It’s incredibly hard to win 100+ games two years in a row these days. The last team to do it was St. Louis in 2004 and 2005.neil: Although maybe the craziest thing there is that, by Pythagoras, the Cubs “should” have won 107 games last year. They underachieved to 103 wins!Even 95 wins this year will probably be enough to take the division, though. Especially if the projections (see above) are to be believed.But I also think those projections are pretty shocking. They have Pittsburgh second?!? I was tempted to think that the Pirates’ 2013-15 mini-run basically ended with the 78 wins they posted in 2016.craigjedwards: Pittsburgh has put itself in a difficult position, trying to contend with a low payroll. Most teams at that end of the financial spectrum — like Milwaukee and Cincinnati, to keep it in the NL Central — can get a few good years in before having to do at least a minor rebuild, but the Pirates are still really close to contending for the next few seasons.neil: What went wrong last season?craigjedwards: Gerrit Cole wasn’t himself, Juan Nicasio didn’t work out as the Pirates’ annual reclamation project and Ivan Nova didn’t arrive until too late in the season. Yet they still weren’t that far off from contending last year, despite a really mediocre season from their best player, Andrew McCutchen.natesilver: The projection systems are all frustratingly non-committal on McCutchen, projecting him to bounce about halfway back instead of either the full recovery or the full collapse. Which undoubtedly makes sense if you average him over a whole range of scenarios. But it seems like there has to be a wide distribution of possibilities there, and that’s very much going to affect the Pirates’ fortunes.neil: Yeah, maybe no team’s season is hinging more on one player’s projection being in the high range rather than the low.craigjedwards: He’s also making the transition to an outfield corner, which is generally not good for a player’s value. But if you are just looking at last year’s defensive numbers (which generally isn’t big enough an indicator of a player’s ability), he’s going to get better just because he isn’t really one of the worst outfielders in baseball.natesilver: I get worried when the indicators for a guy’s athleticism are down. McCutchen doesn’t steal many bags any more. He grounded into a lot of double plays. He’s overmatched in center field, according to the advanced metrics.neil: And the list of McCutchen-like players from history is no help. Some were good after age 30 (Reggie Smith, Andre Dawson); others were already in decline (Vernon Wells, Matt Kemp).The other half of that tandem fighting for second place is the St. Louis Cardinals, who are slated for only 81 or 82 wins if you believe the projections above. Do we buy these third-place projections for St. Louis? Or are they discounting the Cards? (Who still won 86 games last year, with 88 Pythagorean wins.)craigjedwards: The projections for Pittsburgh are all bunched together around 82 wins, while the Cardinals have a couple 84s and a 78 from PECOTA (which keeps their average down). Most of the projections that have the Cardinals higher believe in their pitching and maybe a slight uptick on defense, while PECOTA doesn’t believe in either of those things.natesilver: It’s been a while since I tracked the performance of the different projection systems religiously, but the Cardinals were a team that had a long track record of beating their projections. Maybe it’s because they always tend to be good at player development and have guys play up to their 60th- or 70th-percentile numbers.neil: One area where it seems like there might be a lot of uncertainty is in the pitching, like you mentioned Craig, since their rotation was down from 2015’s fantastic performance. What was different last year, and will they be able to recapture that 2015 form this season?craigjedwards: The blame has mostly gone to the defense, and the Cardinals were pretty bad last year. But they also lost Lance Lynn and John Lackey from the rotation, and Michael Wacha and Adam Wainwright weren’t their usual pitching selves.neil: They’ve also done a lot of roster reshuffling and added Dexter Fowler (granting that his fielding metrics are sometimes mixed). Will all that help fix the defense? Or is that just wishful thinking?craigjedwards: I think Fowler will make the defense better. Randal Grichuk moves from center to left, where, defensively, he’s a big upgrade on Matt Holliday and Brandon Moss. So even if Fowler is a bit below-average for a center fielder on defense, it will still make the outfield defense on the whole better than it was last season.They aren’t going to be great on defense, they just need to not be really bad.neil: Final Q on the Cards: Craig wrote last season that Mike Matheny should be fired. Is he keeping this team from reaching its full potential? Or isn’t there research showing that managers don’t really matter very much?craigjedwards: I think tactically, there isn’t a whole lot of difference between good and bad managers, though I’m not sure too many people really defend Matheny’s bullpen management or in-game decisions.natesilver: And isn’t it plausible that managers matter more than they used to, given how bullpens are used these days? That’s an area where you might expect to see quite a bit of difference, especially in the NL, where you also have to account for pitchers hitting for themselves, etc.craigjedwards: Another problem with Matheny is what appears to be a disconnect with the front office. He’s had big problems playing younger players when they are given to him, to the point that trades had to be made. It would be one thing if he just made poor strategic decisions and relied on small samples to determine whether a player was hot or cold, but it is getting to the point where he also has trouble following through with the front office’s plans.This is going to be a big year for Matheny. He got a lot of credit for managing the Cardinals to the postseason, and he will get blame if they don’t make it. That’s not fair, but it doesn’t mean Matheny deserves to keep a job that was a complete gift to him in the first place.neil: Whichever team prevails between Pittsburgh and St. Louis, they and the Cubs are still far, far above the teams at the bottom of this division: the Brewers and Reds.Let’s start with Milwaukee. Over the past few years, the Brewers seem to be emulating the successful teardown/rebuild models seen recently in Chicago and Houston (and maybe Atlanta next). How’s that going for them?craigjedwards: Milwaukee is doing all the right things. They aren’t going to be able to completely mimic the Cubs — they can’t go out and sign big-name veterans like Jon Lester, Ben Zobrist, John Lackey and Jason Heyward — but they are on the right track. They got one of the top prospects in baseball (Lewis Brinson) from the Rangers in the Jonathan Lucroy trade, picked up another one (Corey Ray) from the draft, and they have a handful of pitchers with potential.neil: So what’s the next step if you’re trying that type of rebuilding effort, but without the Cubs’ resources?craigjedwards: Well, the Brewers are carrying half the payroll they had when they were contending, so they have to play younger guys with potential or trade value (Jonathan Villar, Orlando Arcia, Domingo Santana and Keon Broxton) and deal away relievers whenever they seem to have value. The fans in Milwaukee still support the team, and they will do very well if they can get a winner there. The Ryan Braun question looms, and it’s going to be hard to contend with the Cubs, Pirates and Cardinals in the same division. But they’re making progress.neil: Meanwhile, the Reds are kind of a mess. They had one of the worst pitching staffs ever last year — particularly in the bullpen.natesilver: I’ve become slightly obsessed with modern bullpens, and it’s actually sort of hard/amazing to have a bullpen as bad as Cincy’s in an era where you can take a failed No. 4 starter and turn him into a 2.50 ERA / 10.0 K/9 guy.neil: The Reds have also traded away a lot of veterans in recent years — Todd Frazier, Aroldis Chapman, Jay Bruce, etc. — yet still only have the 13th-best farm system in MLB. Should they have gotten more in return prospect-wise? Also, when will Joey Votto join that group? Can they realistically get fair value for him?natesilver: Votto is sort of the Carmelo Anthony of MLB.neil: Although I will say, the Reds have won a championship in my lifetime, unlike the Knicks.natesilver: The Reds ranked 22nd in WAR last year among players acquired through the draft, which isn’t going to cut it in a small market. So I wonder if there isn’t some longer-term work to do on scouting and development.craigjedwards: I think for a small-market team to succeed, one of the biggest factors is starting pitching because it is so hard to acquire, either in terms of cost in free agency or in trades. Having a cost-effective rotation — like we saw with Cleveland last year and the Mets the year before, or even going all the way back to Oakland’s Moneyball days — can make a big difference for a team trying to push itself into contention.natesilver: Just to bring it back to the Cubs, the thing to remember is that even if you had a team with 103-win talent — and the Cubs probably aren’t *quite* there — they’d still only have something like a 15 percent to 20 percent chance to win the World Series, given how random the playoffs can be. So if we’re thinking in terms of dynasties, there’s a question of how we’d measure one. It’s likely to be a *long* time before we see another team run off three World Series in a row, or four in five years, even if they’re the best team in baseball the whole time.neil: That’s a great point. As terrific as the Cubs are, baseball is a lot more chaotic than, say, basketball. So compared with, say, NBA teams against the Warriors, other MLB teams have a much better chance as they target the Cubs. And that also means the Pirates and Cardinals — if not the Brewers and Reds — have plenty of reasons for hope this season. RANKTEAMPECOTAFANGRAPHSDAVENPORTWESTGATEAVERAGE 3St. Louis Cardinals7884808481.4 EXPECTED NUMBER OF WINS 4Milwaukee Brewers7770737072.4 1Chicago Cubs9395959794.9 In honor of the 2017 Major League Baseball season, which starts April 2, FiveThirtyEight is assembling some of our favorite baseball writers to chat about what’s ahead. Today, we focus on the National League Central with FanGraphs writer Craig Edwards and FiveThirtyEight editor-in-chief Nate Silver. The transcript below has been edited. 2Pittsburgh Pirates8182838382.1 How forecasters view the NL Central read more

Burton boss wants to make history

first_imgFor Nigel Clough, a single goal against Manchester City would suffice to make his team very happy after losing 9-0 in the first leg of the Football League Cup Semifinal.Manchester City defeated Burton 9-0 in the first leg of the Football League Cup Semifinal.The small Football League One club could not compete against the English Premier League side.And they are set to play tomorrow again in the second leg.For Burton boss Nigel Clough, a single goal would suffice to make his side very proud before being eliminated from the competition.“It will be about little milestones and pride of course,” said Clough to the BBC.“If one of our players could score against one of the best teams in Europe then that would be a milestone for us.”Premier LeaguePremier League Betting: Match-day 5 Stuart Heath – September 14, 2019 Going into the Premier League’s match-day five with a gap already beginning to form at the top of the league. We will take a…“And it would be a wonderful individual milestone for whoever got a goal.”“It will probably never happen again. To beat the team’s we have beaten to get here and end up in the last four with Manchester City, Chelsea, and Tottenham – three of the best sides in Europe,” he added.“It’s amazing, really, and the fact that the semi-finals are over two legs helps emphasize that.”Burton Albion defeated Premier League side Burnley, and Championship teams Aston Villa, Nottingham Forest, and Middlesbrough to be able to play against City.The team was founded 69 years ago and last season played in the Championship before being relegated.The Brewers have never been able to reach the Premier League.last_img read more

Will the Workplace Lead Wearable Technology Adoption

first_img 3 min read Consumer adoption of devices such as smart watches, eyeglasses, or fitness monitors is far from mainstream, at least from a global view. Still, almost three-quarters of the 9,100-plus people surveyed last month by Harris Interactive see potential benefits in workplace efficiency, productivity, and safety. Positive sentiment is especially high in Mexico, India and China.The research was conducted on behalf of the Workforce Institute at human resources software and services company Kronos. The online poll during early September (right around the time of the Apple Watch launch) reached 9,126 adults ages 18 or older in Australia, China, France, Germany, Great Britain, India, Mexico, and the United States.“There’s a strong belief that wearable technology will take off in the workplace before the home because devices such as smart watches, intelligent ID badges, and fitness and health monitors can provide organizations with uncharted data collection points to greatly improve safety, productivity, collaboration, and overall workplace effectiveness,” says Workforce Institute director Joyce Maroney, in a statement about the findings.She notes: “And while more and more types of wearable technologies have hit the market, the concept of wearables at work isn’t new. Workers have been wearing uniforms, safety gear, ID badges, communications headsets, and so on for years to do their jobs better.”As a whole, U.S. adults were the least optimistic respondents. For example, only 48% saw a workplace benefit from wearables, versus almost 96% in Mexico, 94% in China and 91% in India. Approximately 13% of the U.S. respondents used wearables in their personal lives, compared with 73% of those from China.The U.S. prospects for wearables in the workplace look far brighter if you look at responses from just those classified as students: almost 72% could cite at least one business benefit (compared with 48% of all U.S. respondents).That finding echoes separate survey results released last week by PricewaterhouseCoopers that suggest 53% of Millennials are “excited” about the future of wearables, particularly in retail, entertainment, and personal healthcare applications.To that end, it’s worth noting that data generated by wearables, particularly fitness bracelets that monitor exercise and health vitals, is fast becoming a must-have component of products and services offered by weight-loss businesses.On Tuesday, Medifast disclosed a partnership with Fitbit and joined competitors Weight Watchers and Nutrisystems in launching apps for tracking nutrition, weight, sleep patterns and other data integral to gauging progress. “Studies show that people who use journaling and tracking systems have far greater success with healthy weight management than those who do not,” said Medifast CEO Mike MacDonald, in a statement.Whether the weight-loss industry is getting ahead of itself remains to be seen. Then again, there could be 130 million wearable devices on people’s wrists, heads and bodies by 2018—an adoption rate akin to those for tablet computers. Growing a business sometimes requires thinking outside the box. Register Now » Free Webinar | Sept. 9: The Entrepreneur’s Playbook for Going Global This story originally appeared on Fortune Magazine October 29, 2014last_img read more

8 recipes to master Promises in ECMAScript 2018

first_img console.log(‘Before promise created’); console.log(‘Before promise created’); console.log(‘Before promise created’); console.log(‘Before promise created’); console.log(‘After promise created’); } Create a function addBoosters that throws an error: function addBoosters (rocket) { throw new Error(‘Unable to add Boosters’); } Create a function performGuidanceDiagnostic that returns a promise that rejects an error: function performGuidanceDiagnostic (rocket) { return new Promise(function (resolve, reject) { reject(new Error(‘Unable to finish guidance diagnostic’)); }); } Use Promise.resolve to pass the rocket object to these functions, and chain a catch off each of them: export function main() { new Promise(function (resolve) { }); console.log(‘Before promise created’); const rocket = {}; Promise.all([]) console.log(‘After promise created’); } Attach a then call to the chain and log that the rocket is ready for launch: const rocket = {}; Promise.all([ Promise.resolve(rocket).then(addBoosters), Promise.resolve(rocket).then(performGuidanceDiagnostic), Promise.resolve(rocket).then(loadCargo) ]).then(function (results) { console.log(‘Rocket ready for launch’); console.log(results); }); Start your Python web server and open the following link in your browser:http://localhost:8000/. You should see the following output: How it works… Promise.all is similar to Promise.resolve; the arguments are resolved as promises. The difference is that instead of a single result, Promise.all accepts an iterable argument, each member of which is resolved individually. In the preceding example, you can see that each of the promises is initiated immediately. Two of them are able to complete while performGuidanceDiagnostic continues. The promise returned by Promise.all is fulfilled when all the constituent promises have been resolved. The results of the promises are combined into an array and propagated down the chain. You can see that three references to rocket are packed into the results argument. And you can see that the operations of each promise have been performed on the resulting object. There’s more As you may have guessed, the results of the constituent promises don’t have to return the same value. This can be useful, for example, when performing multiple independent network requests. The index of the result for each promise corresponds to the index of the operation within the argument to Promise.all. In these cases, it can be useful to use array destructuring to name the argument of the then callback: Promise.all([ findAstronomers, findAvailableTechnicians, findAvailableEquipment ]).then(function ([astronomers, technicians, equipment]) { // use results for astronomers, technicians, and equipment }); Handling errors with Promise.catch In a previous recipe, we saw how to fulfill a promise with an error state using reject, and we saw that this triggers the next catch callback in the promise chain. Because promises are relatively easy to compose, we need to be able to handle errors that are reported in different ways. Luckily promises are able to handle this seamlessly. In this recipe, we’ll see how Promises.catch can handle errors that are reported by being thrown or through rejection. How to do it… Open your command-line application and navigate to your workspace. Create a new folder named 3-07-handle-errors-promise-catch. Copy or create an index.html that loads and runs a main function from main.js. Create a main.js file with a main function that creates an object named rocket: export function main() { return new Promise(function (resolve) { setTimeout(function () { console.log(‘guidance diagnostic complete’); rocket.guidanceDiagnostic = ‘Completed’; resolve(rocket); }, 2000); }); } Create a function named loadCargo that adds a payload to the cargoBay: function loadCargo (rocket) { console.log(‘loading satellite’); rocket.cargoBay = [{ name: ‘Communication Satellite’ }] return rocket; } Use Promise.resolve to pass the rocket object to these functions within Promise.all: export function main() { console.log(‘Before promise created’); Promise.resolve(Math.random() > 0.5) .then(addBoosters) .then(() => console.log(‘Ready for launch: ‘)) What are Promises in ECMAScript? In earlier versions of JavaScript, the callback pattern was the most common way to organize asynchronous code. It got the job done, but it didn’t scale well. With callbacks, as more asynchronous functions are added, the code becomes more deeply nested, and it becomes more difficult to add to, refactor, and understand the code. This situation is commonly known as callback hell. Promises were introduced to improve on this situation. Promises allow the relationships of asynchronous operations to be rearranged and organized with more freedom and flexibility. In this context, today we will learn about Promises and how to use it to create and organize asynchronous functions. We will also explore how to handle error conditions. Creating and waiting for Promises Promises provide a way to compose and combine asynchronous functions in an organized and easier to read way. This recipe demonstrates a very basic usage of promises. This recipe assumes that you already have a workspace that allows you to create and run ES modules in your browser for all the recipes given below: How to do it… Open your command-line application and navigate to your workspace. Create a new folder named 03-01-creating-and-waiting-for-promises. Copy or create an index.html that loads and runs a main function from main.js. Create a main.js file that creates a promise and logs messages before and after the promise is created, as well as while the promise is executing and after it has been resolved: // main.js export function main () { const rocket = {}; console.log(‘After promise created’); } Create a function named addBoosters that throws an error if its first parameter is false: function addBoosters(shouldFail) { if (shouldFail) { throw new Error(‘Unable to add Boosters’); } console.log(‘After promise created’); } Create a function named addBoosters that creates an object with boosters to an object: function addBoosters (rocket) { console.log(‘attaching boosters’); rocket.boosters = [{ count: 2, fuelType: ‘solid’ }, { count: 1, fuelType: ‘liquid’ }]; return rocket; } Create a function named performGuidanceDiagnostic that returns a promise of a successfully completed task: function performGuidanceDiagnostic (rocket) { console.log(‘performing guidance diagnostic’); center_img console.log(‘After promise created’); } Start your Python web server and open the following link in your browser:http://localhost:8000/. You will see the following output: How it works… By looking at the order of the log messages, you can clearly see the order of operations. First, the initial log is executed. Next, the promise is created with an executor method. The executor method takes resolve as an argument. The resolve function fulfills the promise. Promises adhere to an interface named thenable. This means that we can chain then callbacks. The callback we attached with this method is executed after the resolve function is called. This function executes asynchronously (not immediately after the Promise has been resolved). Finally, there is a log after the promise has been created. The order the logs messages appear reveals the asynchronous nature of the code. All of the logs are seen in the order they appear in the code, except the Finished promise message. That function is executed asynchronously after the main function has exited! Resolving Promise results In the previous recipe, we saw how to use promises to execute asynchronous code. However, this code is pretty basic. It just logs a message and then calls resolve. Often, we want to use asynchronous code to perform some long-running operation, then return that value. This recipe demonstrates how to use resolve in order to return the result of a long-running operation. How to do it… Open your command-line application and navigate to your workspace. Create a new folder named 3-02-resolving-promise-results. Copy or create an index.html that loads and runs a main function from main.js. Create a main.js file that creates a promise and logs messages before and after the promise is created: // main.js export function main () { return { boosters: [{ count: 2, fuelType: ‘solid’ }, { count: 1, fuelType: ‘liquid’ }] }; } Use Promise.resolve to pass a Boolean value that is true if a random number is greater than 0.5 to addBoosters: export function main() { const rocket = {}; Promise.resolve(rocket).then(addBoosters) .catch(console.error); Promise.resolve(rocket).then(performGuidanceDiagnostic) .catch(console.error); console.log(‘After promise created’); } Within the promise, resolve a random number after a 5-second timeout: new Promise(function (resolve) { setTimeout(function () { resolve(Math.random()); }, 5000); }) Chain a then call off the promise. Pass a function that logs out the value of its only argument: new Promise(function (resolve) { setTimeout(function () { resolve(Math.random()); }, 5000); }).then(function (result) { console.log(‘Long running job returned: %s’, result); }); Start your Python web server and open the following link in your browser:http://localhost:8000/. You should see the following output: How it works… Just as in the previous recipe, the promise was not fulfilled until resolve was executed (this time after 5 seconds). This time however, we passed the called resolve immediately with a random number for an argument. When this happens, the argument is provided to the callback for the subsequent then function. We’ll see in future recipes how this can be continued to create promise chains. Rejecting Promise errors In the previous recipe, we saw how to use resolve to provide a result from a successfully fulfilled promise. Unfortunately, the code doesn’t always run as expected. Network connections can be down, data can be corrupted, and uncountable other errors can occur. We need to be able to handle those situations as well. This recipe demonstrates how to use reject when errors arise. How to do it… Open your command-line application and navigate to your workspace. Create a new folder named 3-03-rejecting-promise-errors. Copy or create an index.html that loads and runs a main function from main.js. Create a main.js file that creates a promise, and logs messages before and after the promise is created and when the promise is fulfilled: new Promise(function (resolve) { resolve(); }).then(function (result) { console.log(‘Promise Completed’); }); Add a second argument to the promise callback named reject, and call reject with a new error: new Promise(function (resolve, reject) { reject(new Error(‘Something went wrong’); }).then(function (result) { console.log(‘Promise Completed’); }); Chain a catch call off the promise. Pass a function that logs out its only argument: new Promise(function (resolve, reject) { reject(new Error(‘Something went wrong’); }).then(function (result) { console.log(‘Promise Completed’); }).catch(function (error) { console.error(error); }); Start your Python web server and open the following link in your browser:http://localhost:8000/. You should see the following output: How it works… Previously we saw how to use resolve to return a value in the case of a successful fulfillment of a promise. In this case, we called reject before resolve. This means that the Promise finished with an error before it could resolve. When the Promise completes in an error state, the then callbacks are not executed. Instead we have to use catch in order to receive the error that the Promise rejects. You’ll also notice that the catch callback is only executed after the main function has returned. Like successful fulfillment, listeners to unsuccessful ones execute asynchronously. See also Handle errors with Promise.catch Simulating finally with Promise.then Chaining Promises So far in this article, we’ve seen how to use promises to run single asynchronous tasks. This is helpful but doesn’t provide a significant improvement over the callback pattern. The real advantage that promises offer comes when they are composed. In this recipe, we’ll use promises to combine asynchronous functions in series. How to do it… Open your command-line application and navigate to your workspace. Create a new folder named 3-04-chaining-promises. Copy or create an index.html that loads and runs a main function from main.js. Create a main.js file that creates a promise. Resolve a random number from the promise: new Promise(function (resolve) { resolve(Math.random()); }); ); Chain a then call off of the promise. Return true from the callback if the random value is greater than or equal to 0.5: new Promise(function (resolve, reject) { resolve(Math.random()); }).then(function(value) { return value >= 0.5; }); Chain a final then call after the previous one. Log out a different message if the argument is true or false: new Promise(function (resolve, reject) { resolve(Math.random()); }).then(function (value) { return value >= 0.5; }).then(function (isReadyForLaunch) { if (isReadyForLaunch) { console.log(‘Start the countdown! ‘); } else { console.log(‘Abort the mission. ‘); }}); Start your Python web server and open the following link in your browser:http://localhost:8000/. If you are lucky, you’ll see the following output: If you are unlucky, we’ll see the following output: How it works… We’ve already seen how to use then to wait for the result of a promise. Here, we are doing the same thing multiple times in a row. This is called a promise chain. After the promise chain is started with the new promise, all of the subsequent links in the promise chain return promises as well. That is, the callback of each then function is resolve like another promise. See also Using Promise.all to resolve multiple Promises Handle errors with Promise.catch Simulating finally with a final Promise.then call Starting a Promise chain with Promise.resolve In this article’s preceding recipes, we’ve been creating new promise objects with the constructor. This gets the jobs done, but it creates a problem. The first callback in the promise chain has a different shape than the subsequent callbacks. In the first callback, the arguments are the resolve and reject functions that trigger the subsequent then or catch callbacks. In subsequent callbacks, the returned value is propagated down the chain, and thrown errors are captured by catch callbacks. This difference adds mental overhead. It would be nice to have all of the functions in the chain behave in the same way. In this recipe, we’ll see how to use Promise.resolve to start a promise chain. How to do it… Open your command-line application and navigate to your workspace. Create a new folder named 3-05-starting-with-resolve. Copy or create an index.html that loads and runs a main function from main.js. Create a main.js file that calls Promise.resolve with an empty object as the first argument: export function main () { Promise.resolve({}) } Chain a then call off of resolve, and attach rocket boosters to the passed object: export function main () { Promise.resolve({}).then(function (rocket) { console.log(‘attaching boosters’); rocket.boosters = [{ count: 2, fuelType: ‘solid’ }, { count: 1, fuelType: ‘liquid’ }]; return rocket; })} Add a final then call to the chain that lets you know when the boosters have been added: export function main () { Promise.resolve({}) .then(function (rocket) { console.log(‘attaching boosters’); rocket.boosters = [{ count: 2, fuelType: ‘solid’ }, { count: 1, fuelType: ‘liquid’ }]; return rocket; }) .then(function (rocket) { console.log(‘boosters attached’); console.log(rocket); })} Start your Python web server and open the following link in your browser: http://localhost:8000/. You should see the following output: How it works… Promise.resolve creates a new promise that resolves the value passed to it. The subsequent then method will receive that resolved value as it’s argument. This method can seem a little roundabout but can be very helpful for composing asynchronous functions. In effect, the constituents of the promise chain don’t need to be aware that they are in the chain (including the first step). This makes transitioning from code that doesn’t use promises to code that does much easier. Using Promise.all to resolve multiple promises So far, we’ve seen how to use promises to perform asynchronous operations in sequence. This is useful when the individual steps are long-running operations. However, this might not always be the more efficient configuration. Quite often, we can perform multiple asynchronous operations at the same time. In this recipe, we’ll see how to use Promise.all to start multiple asynchronous operations, without waiting for the previous one to complete. How to do it… Open your command-line application and navigate to your workspace. Create a new folder named 3-06-using-promise-all. Copy or create an index.html that loads and runs a main function from main.js. Create a main.js file that creates an object named rocket, and calls Promise.all with an empty array as the first argument: export function main() { console.log(‘Before promise created’); console.log(‘After promise created’); } Add a then function to the chain that logs a success message: export function main() { console.log(‘Before promise created’); Promise.resolve(Math.random() > 0.5) .then(addBoosters) const rocket = {}; Promise.all([ Promise.resolve(rocket).then(addBoosters), Promise.resolve(rocket).then(performGuidanceDiagnostic), Promise.resolve(rocket).then(loadCargo) ]); console.log(‘After promise created’); } Start your Python web server and open the following link in your browser:http://localhost:8000/. You should see the following output: How it works… As we saw before, when a promise is fulfilled in a rejected state, the callback of the catch functions is triggered. In the preceding recipe, we see that this can happen when the reject method is called (as with performGuidanceDiagnostic). It also happens when a function in the chain throws an error (as will addBoosters). This has similar benefit to how Promise.resolve can normalize asynchronous functions. This handling allows asynchronous functions to not know about the promise chain, and announce error states in a way that is familiar to developers who are new to promises. This makes expanding the use of promises much easier. Simulating finally with the promise API In a previous recipe, we saw how catch can be used to handle errors, whether a promise has rejected, or a callback has thrown an error. Sometimes, it is desirable to execute code whether or not an error state has been detected. In the context of try/catch blocks, the finally block can be used for this purpose. We have to do a little more work to get the same behavior when working with promises In this recipe, we’ll see how a final then call to execute some code in both successful and failing fulfillment states. How to do it… Open your command-line application and navigate to your workspace. Create a new folder named 3-08-simulating-finally. Copy or create an index.html that loads and runs a main function from main.js. Create a main.js file with a main function that logs out messages for before and after promise creation: export function main() { console.log(‘Before promise created’); console.log(‘After promise created’); } Add a catch to the chain and log out the error if thrown: export function main() { console.log(‘Before promise created’); Promise.resolve(Math.random() > 0.5) .then(addBoosters) .then(() => console.log(‘Ready for launch: ‘)) .catch(console.error) console.log(‘After promise created’); } Add a then after the catch, and log out that we need to make an announcement: export function main() { new Promise(function (resolve) { console.log(‘Executing promise’); resolve(); }).then(function () { console.log(‘Finished promise’); }); console.log(‘Before promise created’); Promise.resolve(Math.random() > 0.5) .then(addBoosters) .then(() => console.log(‘Ready for launch: ‘)) .catch(console.error) .then(() => console.log(‘Time to inform the press.’)); console.log(‘After promise created’); } Start your Python web server and open the following link in your browser:http://localhost:8000/. If you are lucky and the boosters are added successfully, you’ll see the following output: 12. If you are unlucky, you’ll see an error message like the following: How it works… We can see in the preceding output that whether or not the asynchronous function completes in an error state, the last then callback is executed. This is possible because the catch method doesn’t stop the promise chain. It simply catches any error states from the previous links in the chain, and then propagates a new value forward. The final then is then protected from being bypassed by an error state by this catch. And so, regardless of the fulfillment state of prior links in the chain, we can be sure that the callback of this final then will be executed. To summarize, we learned how to use the Promise API to organize asynchronous programs. We also looked at how to propagate results through promise chains and handle errors. You read an excerpt from a book written by Ross Harrison, titled ECMAScript Cookbook. It’s a complete guide on how to become a better web programmer by writing efficient and modular code using ES6 and ES8. Read Next: What’s new in ECMAScript 2018 (ES9)? ECMAScript 7 – What to expect? Modular Programming in ECMAScript 6last_img read more