美团外卖团队队怎么开?

列表网公众号列表活动随时有扫我活动不错过
微信扫一扫快速获取电话
微信扫一扫快速获取电话
微信扫一扫快速获取电话
微信扫一扫快速获取电话
微信扫一扫快速获取电话
微信扫一扫快速获取电话
微信扫一扫快速获取电话
外卖油焖大虾&
微信扫一扫快速获取电话
微信扫一扫快速获取电话
微信扫一扫快速获取电话
微信扫一扫快速获取电话
微信扫一扫快速获取电话
微信扫一扫快速获取电话
微信扫一扫快速获取电话
微信扫一扫快速获取电话
食一点外卖&
微信扫一扫快速获取电话
微信扫一扫快速获取电话
微信扫一扫快速获取电话
微信扫一扫快速获取电话
微信扫一扫快速获取电话
微信扫一扫快速获取电话
微信扫一扫快速获取电话
微信扫一扫快速获取电话
微信扫一扫快速获取电话
微信扫一扫快速获取电话
清蒸大闸蟹&
微信扫一扫快速获取电话
微信扫一扫快速获取电话
外卖油焖大虾&
微信扫一扫快速获取电话
微信扫一扫快速获取电话
微信扫一扫快速获取电话
微信扫一扫快速获取电话
外卖油焖大虾&
微信扫一扫快速获取电话
微信扫一扫快速获取电话
微信扫一扫快速获取电话
微信扫一扫快速获取电话
微信扫一扫快速获取电话
微信扫一扫快速获取电话
微信扫一扫快速获取电话
微信扫一扫快速获取电话
微信扫一扫快速获取电话
微信扫一扫快速获取电话
微信扫一扫快速获取电话
微信扫一扫快速获取电话
微信扫一扫快速获取电话
微信扫一扫快速获取电话
微信扫一扫快速获取电话
油焖大虾外卖&
微信扫一扫快速获取电话
微信扫一扫快速获取电话
微信扫一扫快速获取电话
油焖大虾外卖&
微信扫一扫快速获取电话
餐饮美食相关分类:
餐饮美食相关搜索词:
武汉生活服务所有分类:
&2017 列表网&琼ICP备号-12&增值电信业务经营许可证B2-&
还没关注列表网?一大波金豆等你拿!更多数码资讯,请关注南窗数码
“快跑团队”相关经验又赚钱的9种职业积极寻找属于自己的&第361行&吧!它可以是加入国际义工组织到世界各地体验不一样的人生,它可以在网上书城做个全职书虫,只要做爱做的事,工作着才是快乐的。美食旅行家出国旅行少不了的就是品尝当地原汁原味的美食,以感受最真实的风土人情。既然如此,为什么不打正旗号,尽兴而行呢?以一本《厨房机秘档案》闻名全球的纽约名厨波登,日前就出发到世界各地旅行,一边吃一边撰写《名厨吃四方》,用独特的厨师观点来看这个世界。行程走到后半部,Knowledge旅游探险频道两位摄影师一同加入这个全球吃透透的计划,因为只有这样结合食物本身、用餐情境与回忆的绝佳组合才是波登心目中的超完美美食,这样的工作才是世界上最棒的工作。服装选购员心情好的时候买衣服,不好的时候也买衣服。然而激情过后,面对的就是衣柜里日渐积压的衣服成为包袱。想起张艾嘉电影《心动》里的梁咏琪,成年累月就是从香港飞往巴黎,巴黎飞东京,东京到纽约,从一个时装秀场到另一个时装秀场,从一家家时装品牌的新产品挑选最适合香港市场的款式,从一个个展示橱窗及Model身上感受当季最流行的设计,从一件件待选服装中幻想名利场上的衣鬓香影,幻想别人的&皇帝的新装&,这样的工作,才真正让人心动。儿童漫画师做《我梦见》的专题时,有位说她最希望自己回到六岁前的生活,因为那时的自己无忧无虑。朋友阅读杂志习惯先看最后面的朱德庸&绝对小孩&,因为&令人好好笑&。默非在《史奴比、小王子和成人儿童主义》中有句话:&对于小孩子来说,想象力是他的世界;而对于大人们来说,想象力是对自己的关怀。&几米式的、麦兜式的&长不大&是一种放松,&幼稚&给我们带来微笑,它们最大的能力是让人重拾温暖的童真。那么创作这些故事的作者呢?几米说过:&能画出自己的故事,是一件很过瘾的事。&国际游学者周游世界?这是人类共同理想之一。但我最希冀的是像当年欧洲的绅士贵族们开始自己人生的一次贵族游学,用几年或更长的时间游历欧洲大陆乃至全球更多的地方,体验更多的人生。但我们当中有几个拥有贵族般的条件呢?没有。大学后通过学术交流的机会到香港着名大学生活几年,然后又通过参加国际红十字的机会到达美洲继续行程。以社会义工体验、游学,这可能才是纯粹的完美旅程。先驱级书虫职业杀价手对于通晓购物杀价的人来说,讨价还价是一种生活乐趣。习惯到传统菜市场买菜的人大都并不乐意到超级市场购物,因为一旦到了明码实价的地方,三寸不烂之舌便无用武之地,哪怕再特的特价也是&吃龙肉都不开心&。但沈阳日前就出现了职业的砍价人,只要你足够专业,足够有把握,除了能服务于家庭,服务于亲友,还能服务于大众&&为有需要的购物人有偿服务,大有&天下寒士俱欢颜&的淋漓畅快。专职选美人女人的美丽本来就是一种可以换到各种职业的人生资本,换财富,换爱情,换伴侣。从一个选美赛场换到另一个选美赛场,从地方性到国家性再到国际性,迎接掌声鲜花挑剔和各种看不见的机会,就像那些还没红的小明星,从一个广告或是电视剧换到另一个之中,这就是我们俗称的漂浮却又快乐的饭吧。专业&八婆&做一件人人都看得见的工作,也许你就可以把它想象成一种快乐的工作了。你在人前人后对明星指指点点,并且说得头头是道,至少在女人堆里,这样的八卦只会越来越增加你的受欢迎度。尽管这份工作中看得见的名誉越来越少了,可在全民八卦程度极度上升的时代里,这是份最能娱乐大众、最能使人快乐的工作;尽管对于一个敬业的娱记来说,工作一定是劳累、痛苦并且迷惑的。积木堆砌师什么工作是整天玩乐高积木的?答案就是当乐高乐园的设计师。美国加州乐高乐园日前征选设计师,面试需时两天,内容就是使出浑身解数,用四千块乐高积木,堆砌出和乐高主题公园相关的作品,形式自由发挥,既可以是八爪鱼公园,也可以是一艘船,一座城堡。这个时候需要的就是&童心未泯&,让自己过一个大人的&童年&。然而最cool的大抵是成为乐高设计师后,可以对别人说:我的工作就是玩乐高积木!拉起团队建&咕噜Grooo&外卖平台创业东北大学秦皇岛分校学生田井新和他的小伙伴们一同搭建了一个针对在校大学生的生活服务平台&&&咕噜Grooo&。这个平台由开发运营团队的30个人、一个APP、一个微信公众号、一个网站、众多商家组成。最先提出这个想法的是苏泊,田井新的同系同学。今年年初,苏泊提出和几个同学开一家超市,大家认为虽然开超市能挣钱,但没啥意思,不如做一个&o2o&的生活服务平台,就从送外卖开始。大家一拍即合。同学焉诗豪负责做微信公众号和网站,来自计算机系的闻一鸣负责写APP。假期过后,软件和网站基本成型,接下来就看运营了。运营是个很麻烦的问题,田井新和几个同学负责这一块。他们和一个个外卖店联系,&刚开始跟商家说话都害羞,现在好多了文章出自,转载请保留此链接!。&田井新说。与外卖店谈合作很顺利,只是很多店主年纪较大,不会用智能手机,他们需要帮店主下载、安装,然后再交给店主用。好多时候,店主当()时说学会用了,但第二天电话就打过来,说接不了单了。遇到这种情况,田井新他们就得赶紧赶过去。送外卖,配送是个大问题。好多外卖店都抱怨,需要一个专门的配送人员,增加了开支。针对这一情况,田井新和他的小伙伴们组建了自己的配送队伍帮外卖店配送。配送是个累活,报酬少了没人干,报酬多了又给不起。他们通过一些措施来解决这个问题,首先把配送时间固定在中午12点和下午6点左右,网上订单下好后,配送人员集中取一次,然后发给各个宿舍楼负责配送的同学,这些学生就住在本栋宿舍楼,他们下课回宿舍的时候顺便就捎上去了,所以配送不用付出太大精力。现在除了送外卖,他们的业务还扩展到超市等。从4月份到现在,他们的配送额有7万多元,&平台能得到配送额的10%到15%作为利润,大家还是有信心做下去的。&田井新说。相关: 咕噜grooo外卖的宣传广告:咕噜grooo是一个咱们学生自己做的外卖平台不管你是喜欢定外卖还是去食堂就餐咕噜都能为你服务(全部都由学生运营,绝对诚信可靠)咕噜grooo还有物流、超市点单等服务(程序员大大正在加班加点的赶制,开学左右都能出来~^O^~敬请期待)咕噜的独到之处1.优质的商家~~我们的商家都是根据各大订餐网站上的数据和同学们的口碑来挑选的。价格绝对公道~味道可口2.一次彻底的物流~直接送到大家的寝室门口,敲门送餐完成物流3.诱人的积分功能~为回馈广大用户~满一定的金额可获得相应积分~可以用积分来换取我们提供的给大家伙们的多种服务例如上门收件和取件快递(对于抽不开身来不及取快递的同学是个好消息啦啦啦给宿舍充值水电费等)4.开启校园食堂预约模式,课前下一单,让您直接取餐,无需等待更多精彩未完待续&&&&&&欢迎关注我们的微信公众号咕噜grooo谢谢大家啦!■专家点评罗国锋:互联网创业成本相对较低,商业模式也可以快速复制。这个平台针对学生吃、喝、用高频率的需要,可以服务于东北大学秦皇岛分校的学生,也可以复制到其他高校。相比其他团购网站,人工成本可控是他们的优势。现在学生的生活方式发生了变化,许多消费过程通过互联网完成,他们可以把学生的这种需要挖掘出来。为何大学生会选择&送外卖&这样的项目开始创业呢?一是学生缺乏创业资金;二就是学生接触面窄,这就决定了他们选择的创业项目多是围绕大学生&衣、食、住、行&这些技术含量比较低、倾向销售类型项目。大学生避开&高精尖&,而选择这些销售作为项目,于大学生创业而言,非但&无害&,还是必要的锻炼,所以说有60%愿意创业的学生首选&送外卖&,是非常值得鼓励。首先在创业整个链条里面,从研发、制造、到销售、售后服务等各个环节里面,研发跟销售是创造价值最核心也就是赚钱最多的两个环节,而一个创业项目的好坏最终都要通过销售这个环节实现与市场对接,因此对大学生创业来说,最具锻炼性;另外大学生接触销售这个环节,还可以通过市场导向作用,发现市场的需求,然后再反馈到创业项目中,通过不断修正技术选择,最终选择适合自己的创业项目;而且,大学生创业应该是一个不断试错的过程,好项目也不是一蹴而就的,需要不断锻炼、不断发掘,我们应该允许大学生一开始创业尝试不同的选择。建议大学生创业还是要做好相关的准备,比如最起码做好市场调研,还有对公司注册、团队组建、资金筹集、业务范围、市场推广等环节也要做好规划,为以后做长远准备。老总和员工当你在办公室里遇到了老总对员工好的时候,你会想到了什么呢?王红应聘到一家公司做文员,刚来这家公司的时候,她感觉这家公司的规模好小。公司里在才几个员工,而且公司有两个老板,他们之间是合伙的关系。王红被安排到了刘总的那个部门,工作一段时间后。她每天工作不多,没有什么乱七八糟的事。她觉得她得这份工作还不错,也满意吧!但是这样清闲没有维持多长时间,因为公司新开了一个项目,老总让她跑这个项目,刚开始她对这个新项目也挺热衷的。因为她觉得如果把这个项目做好,以后自己的小生活会更好的,而且还能学到不少东西。所以她很努力也很喜欢她负责的这个项目,但是有时梦想和现实是有区别的,因为,每次她要去拜访客户的时候,老总非说也一起去,她也没法拒决,说真的,其实和老总一起去拜访客户,这样也提高了她的业绩,让她没有想到的是,老总虽然在一起吃饭的时候,说什么要包养她,这让她却实吓了一大跳,因为她有一个很很温馨的家庭,有个很爱很爱她的老公,女儿也听话也很乖巧,她就从来没有想过,她除了老公之外,还会和其它的男人有什么不清不白的关系,所以,她万万没有想到老总会和她说这么不的话。但是这样也使她陷入的矛盾之中第一、现在的她却实需要一份工作。第二、现在的工作的工资也不算低,她需要钱。第三、她觉得自己如果换了别的工作就找不到这样好的工作条件和环境了。她现在每天都生活在矛盾之中。她不知道她现在到底怎么做才是对自己最好的选择。她对已后的生活好迷茫呀!小编推荐创业故事:免责声明:本文仅代表作者个人观点,与本网无关。看完本文,记得打分哦:很好下载Doc格式文档马上分享给朋友:?知道苹果代表什么吗实用文章,深受网友追捧比较有用,值得网友借鉴没有价值,写作仍需努力相关故事:
48小时热门Uber的外卖团队是如何使用React Native的?
作者:Chris Lewis
译者:大愚若智
原文: /ubereats-react-native/
本文由作者授权翻译并发布,未经许可禁止转载。
Uber基于React Native技术构建的Restaurant Dashboard应用为送餐业务UberEATS提供支持,消除纯Web应用在功能方面的局限,为餐厅共和顾客打造更无缝的订餐体验。
对于UberEATS,我们的目标是让用户能够流畅的从最喜欢的餐厅点外卖,就像通过uberX或uberPOOL约车那样简单。与任何新产品的发布一样,构建一个这样的食品交付网络在工程方面也会遇到各种“喜”和“惊”。
虽然很美味,但这些新的乘客(食物!)本身也给我们带来了不小的挑战。
例如,这些“乘客”无法指定自己想走的路线,也不能和司机闲聊,但是在“乘客”上下车过程中确实需要一些额外的步骤。本文我们将重点介绍其中的一个挑战:Uber工程部门如何在原本只涉及司机和乘客的双边关系中引入第三方。
幸运的是,借助Uber现有的技术栈,我们可以在很短的时间里让UberEATS顺利上线并投入运转。只不过这次,旅途变成了送货,司机变成了“外卖小哥”,乘客变成了食客。不过餐厅在这其中的角色没有什么可供类比的,因为过去五年来,我们都已经习惯于假设一段旅途只会涉及两方人员,更不会有芝士披萨、泰式炒河粉,或者墨西哥鸡肉卷这样的乘客。
构建Restaurant Dashboard
图1:UberEATS市场包含三方人员:餐厅、送货人,以及食客。这种新态势导致Uber传统的双边模式需要做出改变。
餐厅需要通过某种方式与送货人和食客交流。所有涉及方至少需要能传递下列信息:
送货人抵达餐厅
这四个基本需求催生了Restaurant Dashboard(餐厅仪表盘),这是一种基于React/Flux的单页Web应用程序,可通过平板设备访问。
图2:显示有一个活跃订单的Restaurant Dashboard。
面向未来计划中的50城,改造Restaurant Dashboard
自该应用的独立版本于2015年12月在多伦多首发后,我们不断努力打造一种更简单可靠的接口,餐厅可通过该接口就送货相关的事务进行协调。多个月来,我们已经明白,为了继续改进Restaurant Dashboard,有必要进行彻底改造。
我们的Web应用仅能通过设备提供有限的访问能力,而这是个大问题,因为这种方式限制了我们与餐厅就重要事项进行沟通的能力。例如用户必须先打开网页才能听到通知提示音。餐厅工作繁忙,因此通过声音通知餐厅员工有用户下了新订单,或送货人已经抵达准备取餐,这一点非常重要。为了解决这个问题,每次页面载入后,为了吸引用户注意,我们会显示一个模态窗口(Modal)。虽然可以通过这种方式播放声音,但会牺牲用户体验。
图3:Restaurant Dashboard通过显示模态窗口吸引用户注意力进而播放声音。
我们还需要构建一些无法通过网页浏览器实现,或者只能以受到较大约束的方式实现的功能。例如,打印纸质小票是很多餐厅必做的,然而网页浏览器只能通过兼容AirPrint的打印机实现这一点。这样的局限导致餐厅和工程师们感到困惑和沮丧。我们意识到为了克服这些障碍,必须能访问硬件,使用打印机厂商提供的原生SDK直接与打印机通信。
评估React Native
虽然目前来说,把React Native称作移动应用开发中能解决所有问题的“银弹”还有些为时尚早,但该技术确实能很好地满足UberEATS的需求。由于最初设计的Restaurant Dashboard是面向Web的,我们的团队针对React,以及面向iOS/Android有限的暴露已经积累了大量经验。此外大家也非常了解服务中与餐厅有关的组件是如何运作的,我们从UberEATS诞生那天起就在进行各种积累。多方因素考虑,使得React Native这一以Web语言进行移动开发的平台成为最理想的选择。该技术为我们提供了“烹饪”出近乎完美的应用程序所需的全部炊具。
对我们来说,多平台支持很重要。目前Uber正在与餐厅紧密合作,寻找平板设备并安装Restaurant Dashboard应用,但随着UberEATS的不断扩张,这种做法逐渐不那么现实了。早些年当我们过渡至BYOD(自带设备)模式时,Uber的司机也曾面临类似的情况。通过以不依赖具体平台的方式构建UberEATS应用,我们随后将能灵活地扩展至Android,随着进一步成长为每个平台提供完善的支持。
为了顺利使用React Native,还必须确保这技术能在我们现有的移动基础架构中流畅运行,可以支持最初促使我们转换为原生应用程序方式的各类功能。为此我们构建了一个专门用于验证各种关键功能的“演示”应用程序。借此我们可以直接用Uber其他团队提供的原生依赖项进行功能测试,例如崩溃报告、用户身份验证、分析。由于这些功能涵盖了原生Objective-C层以及解释型Java层,借此我们还可以测试要求对两个环境进行集成的功能的交付能力。
总的来说,这个演示实现了我们的目标。诸如崩溃报告等库可以独立于应用程序的业务逻辑运作,并能实现拆箱即用。此外我们发现,通过与Java层进行连接进而提供分析事件等功能,这个过程其实也极为简单。事后总结发现,由于不存在技术障碍,可能导致我们严重依赖原生库,而原生和Java功能之间的矛盾后来也影响到我们很多架构方面的决策。
构建迁移路径
我们最初的目标是通过最少的工作量构建一种让Restaurant Dashboard能够原生运行的框架。为了实现这一点,我们创建了原生的导航和身份验证系统,并通过WebView将其指向现有的Web应用。
图4:上图展示了Restaurant Dashboard Flux存储原生和Web组件之间的交互。
来自WebView的网络请求会使用NSURLProtocol进行修改,以便获得必要的身份验证头。窗口中还额外增加了其他钩子,这样我们就可以更新基于Web的Restaurant Dashboard的Flux存储,将Java注入WebView。这种做法在细化的功能迁移工作中为我们提供了极大的灵活性。
完成了这样一个功能基本完备的最小可行产品(MVP)后,我们可以通过现实中的餐厅快速进行测试。此外在原生功能方面也让我们获得了“快速胜出”的机会。我们集成了多个原生打印机SDK,使得打印机方面的支持扩展到了不兼容AirPrint的更多型号。此外我们还禁用了睡眠模式,实现这一改动只需要一行原生代码,但以往通过Web是根本无法实现的。
随后需要将应用程序的其他部分逐个迁移至React Native。在可能的情况下,我们希望让尽可能多的功能迁移后即可使用,而不是为了重写而重写。
上文提到过,React Native将Web和移动开发融合到了一起,使得我们可以自由选择使用原生或Java的方式编写功能。与这种功能相伴的还有移动和Web社区的相关模式和概念。这种想法方面的融合为我们提供了更多选项,但如何选择最恰当的抽象,也为我们造成了新的挑战。
最终我们为UberEATS制定的架构与普通的React/Redux Web应用架构差不多,我们尽可能避开了iOS模式和模块。幸运的是,对于我们的需求和首选项来说,Web概念和技术从整体来看可以很完美地转换为原生开发模式。
应用的路线功能是这种轻松转换的典范之一。在Web端,Restaurant Dashboard使用了流行的React-router库,借此可用声明地方式清晰地定义线路,具体方式与View中的做法差不多。然而这种系统会假设URL的存在,但浏览器之外通常并没有URL。React Native提供了我们急需的导航库,该功能与UINavigationController提供的接口非常类似。
考虑到速度,最初MVP完成并开始运行时,我们让React-router库取代了Routing框架。不存在的URL问题也很好解决,只需要替换Java中的HTML5 History API即可,毕竟它无论从目的和用途来看都只是一个栈。
当我们需要将React-router迁移至某个React Native库,例如Navigator或NavigationExperimental时,新的实现相比原本的解决方案似乎没法提供任何收益。结果我们发现这是因为无论原生或基于浏览器,Vanilla react-router就仅仅是一个用来做Routing的好方法。
移植过程中学到的另一个宝贵经验是,将iOS与Java之间的交互降至最低,将逻辑全部浓缩至Java层,这种做法大有裨益,例如:
减少Java与Objective-C之间的上下文切换次数
增强可移植性(因为减少了依赖特定平台的代码数量)
减少了Bug的影响范围
随着项目继续进行,我们开发了一个与原生层进行通信的简单API。虽然希望让这一层尽可能薄,但我们也理解需要将多少代码保留在React Native层。诸如分析和登录等功能从本质上来看只是网络调用,可以通过Java相对轻松地实现,然而最开始使用Objective-C编写的代码需要移植到Java才能支持Android。然而我们更愿意借助这个机会使用Java重写这些库,使其可以跨平台使用。
自动推送更新
React Native应用程序可通过少量Objective-C/Java代码实现自举,随后即可加载Java包(Bundle)。这些包已包含在应用程序中,和其他类型的资产一样。但有人建议我们说,如果业务逻辑依然保留在这些包中,应用程序就可以在启动时加载另一个Java文件,借此进行更新,这个过程非常简单。在原生层,应用程序可以更改React Native桥所用的包,并在需要时请求进行重新载入。
为了让更新逻辑不依赖具体平台,我们选择更进一步围绕这个桥建立一个原生包装,借此让Java包自己判断到底要加载哪个包。
图5:Restaurant Dashboard在任何时间最多可以存储三个不同的Java包。
Restaurant Dashboard会定期检查是否有新的包,并会自动下载更新。原生代码和包代码都符合语义化版本(Semantic versioning),每个新部署可分配唯一标识符,需要更改“原生-Java”通信接口的变更会被视作“破坏性”的。例如,将Analytics模块更名为AnalyticsV2会被视作一种“破坏性变更”,因为从Java包到Analytics的现有调用会触发异常。
当然,就算对语义化版本给予最密切的关注,依然可能产生破坏性的更新。在UberEATS的环境中,破坏性的更新是指会导致包处理逻辑还来不及运行,Restaurant Dashboard就已崩溃的包更新。这个时候出现的崩溃会导致无法通过推送新版本包而修复问题。更新造成这种不稳定的局面注定会出现,因此必须具备某种可靠的系统,能够检测到不稳定的构建版本并从中恢复。
避免部署破坏性更新的方法之一是将每个更新视作实验性的,循序渐进地推出更新,并在必要的时候进行回滚。
图6:Restaurant Dashboard的回滚流程判断要加载的包。
为了让回滚流程能够正常生效,Restaurant Dashboard需要能识别哪个包是破坏性的,随后重载“安全”的包(即已知可以正常运行的包,例如应用发布时自带的包),否则将无从确定到底要将软件回滚到哪个版本。为了实现这一功能,我们设计了自动重载最初伴随应用程序一起发布的Java包,随后从推送的两个包中择一加载:最新且安全的包,或最新的包。如果最新的包可以顺利加载,那么可以认为这个包也是安全的。如果没有找到已知安全的包,则不进行任何更新,继续使用最初的包。
相比传统的移动应用更新方式,通过这种方式对Restaurant Dashboard进行更新产生冲突的概率更低,因为新构建可以按需发布,借此可将新功能的发布时间由原本的数周缩短为数天。更新可在后台下载,并在下载完成后自动加载,这一过程无须用户介入。而因为无须用户交互,更新的准备过程可以变得更快,并尽可能确保更多设备始终可以使用最新版本。这样的机制还使得我们可以快速回滚有问题的构建,将软件问题对餐厅造成的影响降至最低。
虽然通过这种方式推送更新的做法还不能完全取代传统的应用发布方式(有关iOS或Android原生代码的变更依然需要通过这种方式进行),但至少降低了传统方法的使用频率。随着项目的原生层逐渐成熟,希望这样的趋势能继续保持下去。
测试和类型检查
在Uber工程团队内部,我们的工作进度很快,Web项目通常会在变更推送至代码库后立刻发布,而不会等待进行构建。相比通常来说发布流程需要持续数周的移动应用程序,这样的做法产生了强烈的反差。在开发Restaurant Dashboard的过程中,当我们考虑到需要转向原生应用时,我们曾担心由于需要进行如此重大的转变,应用程序可能会在稳定性方面遇到问题。毕竟如果React Native解释器崩溃了,现实应用也会崩溃。尽管包推送的方式可以在一定程度上避免这类风险,但距离彻底避免崩溃还有很长的距离。
单元测试和浅渲染(Shallow rendering)已经诞生很久了,但最近在Java社区有越来越多人主张通过Flow或Type的方式并入静态类型检查。
因此这次更新应用时,我们决定使用Flow进行类型检查,这一决定使得我们可以对业务逻辑的准确性更自信。实际上,事实证明这是一种在发布至生产环境之前进行代码测试和获取错误的极为有用的工具。
通过一个简单的范例来看看Flow在类型检查Reducer函数方面的强大能力。如下例所示,Reducer获取了正确的状态和操作作为输入,随后可以返回一个新的状态作为输出:
副作用的解决
使用Flow进行类型检查使得我们可以验证在该过程之后,状态依然可以维持正确结果,同时在Flow社区的无私奉献下,新版本可以在我们的应用程序中找到各种可能的Bug来源。此外由于可选类型只会造成最少量的开销,因此并不会妨碍到我们的快速迭代和开发工作。
Restaurant Dashboard使用Redux管理数据的流动。Redux为我们提供了一种简单、可预测的方法,帮助我们通过下列几个关键原则对应用程序状态进行建模:
所有状态位于Store中,而这种Store是一种单一不可变对象;
View可将Store视作输入,并负责渲染React Native组件;
View可以派遣Action,而Active实际上是一种对Store进行修改的请求;
Reducer接受Action和当前状态作为输入,返回一个新的Store。
为了响应诸如网络请求等异步操作,通常还需要修改Store。Redux并未提供这样做的方法,但此时比较常用的方式是使用Thunks,这是一种面向Redux的中间件,可以让操作成为一种可以返回承诺的函数,并调派其他操作。
图7:在Restaurant Dashboard中,数据可通过Redux应用程序流动。
我们最初的做法是使用Thunks,但随着应用程序逻辑(以及副作用)逐渐变得复杂,很快开始遇到问题。尤其是我们遇到了两种副作用模式,这两种模式无法自然地融入Thunk模型:
对应用程序状态的定期更新
副作用之间的协调
作为Redux应用一种备选的副作用模型,Sagas可以借助ES6(ECMA 6)生成器函数提供一种不那么复杂的选项。此时不需要对操作的概念进行扩展,而是可以作为一个单独的线程进行建模,随后即可访问Store,监听Redux操作,调派新的操作。为了避免与Thunk有关的问题,最近已全盘迁移至Sagas,因此我们可以更放心地进行缩放,并确信该技术的成熟度可以更好地满足自己的需求。(无穷无尽的Saga!)
Sagas最醒目的亮点之一在于对应用程序状态中定期发生的变更进行管理,例如检索活跃订单的最新列表。这一特性也可以通过Thunks实现,但Sagas的做法更优雅。(谁会喜欢用Thunks呢?反正我们不喜欢!)例如组件可以定期调派一个操作来获取订单,当然Thunk也可以递归地调用自身实现类似目标。然而抛开实现方面的问题不谈,不需要使用包含计时器逻辑的组件,也不需要用独立的Thunk持续触发自身,这种方式更适合Redux模式。
针对这种问题,Sagas提供了简明扼要的解决方法,使得我们可以创建收寿命更长的任务,定期获取新订单并调派更新Store所需的操作。
使用寿命更长的任务,这会面临另一个问题:维持任务之间的通信,例如:
以上文获取订单的范例为例,只有在具备有效用户会话的情况下,才能获取订单并更新Store。如果不能强制实施这一规则,可能导致一些不易察觉的错误,例如餐厅注销后订单才能更新的竞争状态。这种情况会进一步产生触发崩溃的边缘案例,或导致界面上显示一些奇怪的提示,因为有关传入订单的代码很有可能假设一个不存在的餐厅是实际存在的。
避免此类问题的做法很简单,但找出潜在的竞争状态并提供必要的检查,这是一种极为耗费时间并且容易出错的过程。更重要的是,我们的订单代码不应考虑用户会话的状态,因为这是两个不相干的问题。
Sagas提供了一种简单的方法,供我们监听与会话有关的操作,进而启动或停止获取订单的后台任务。例如,在看到登录事件后,我们可以派生出一个定期获取订单的任务,如果发现用户注销,则取消该任务。这一切可以在Saga中非常简单地实现,例如:
派生的任务会成为另一个生成器,该任务会持续运行,直到该任务或其父任务终止。
实际上,我们发现这种将特定操作汇聚在一起的方式非常普遍,有些类似于组件修饰器(Decorator),我们可以将这样的逻辑放入更高层的订单生成器函数,例如:
Sagas的本质还简化了我们的测试过程。通过使用Sagas,针对特定功能进行单元测试的过程可以大幅简化,只须调用相关Saga并对结果执行深入对比即可。
这种方式需要让很多小服务通过消息传递的方式相互通信,很多后端工程师对这样的做法已经很熟悉了,但我们生成和使用的是Redux操作,而非Kafka事件。从开发者的角度来说,很高兴能看到这样的模式能够应用于客户端代码。
有关UberEATS旅途的反思
开发一个应用程序的完整心得体会几乎不可能用一篇文章全部概括,尤其是像UberEATS应用程序这样对餐厅的交互产生如此大影响的应用。希望本文能让大家更好地了解我们的团队在决定为UberEATS使用React Native,以及确保为餐厅提供可靠、稳健的用户体验过程中所进行的权衡和考虑。
虽然React Native目前在UberEATS的工程生态中只占据很小的一部分,但我们使用该技术重建Restaurant Dashboard的过程中依然获得了大量宝贵经验。自从去年上线至今,改头换面后的Restaurant Dashboard已经成为几乎所有加盟UberEATS的餐厅不不可少的标准化工具。按照这样的发展速度,我们可以很乐观地估计该框架的能力将可以继续满足我们对规模的需求,帮助我们将这个市场扩展到更多地区。
作者介绍:
Chris Lewis是Uber的软件工程师,主要负责UberEATS的Restaurant Dashboard应用程序。工作的同时,Chris自己也会使用UberEATS从他最喜欢的一家旧金山餐馆订寿司。
活动推荐:
由InfoQ主办的第二届GMTC全球移动技术大会开始报名了!大会将于6月9-10日在北京举行。本届大会,我们将探讨智能时代的大前端,在动态化、React Native等逐渐流行的现在,移动和前端的融合将会发生怎样的变化?点击阅读原文进入大会官网,现在报名享8折优惠!
责任编辑:
声明:本文由入驻搜狐号的作者撰写,除搜狐官方账号外,观点仅代表作者本人,不代表搜狐立场。

我要回帖

更多关于 百度外卖团队 的文章

 

随机推荐