1.介绍promise和模仿Promise.all和Promise.race

promise的设计主要是解决回调地狱(接收结果用回调函数来处理,但必须传入回调函数)的问题,由一层层嵌套回调函数改为由then来执行。

例如:

 
// callback用于接收返回结果, 异步方式
fs.readFile("filePath", callback);
// 还有一种方式
cosnt { promises: fs } = require("fs"); // 用promise包装fs模块,已经实现
fs.readFile("filePath").then(callback); // 由上可看出,promise只是解决了回调函数的调用方式,没有彻底改变回调函数继续存在的问题。

promise有三个状态,分别是pending, resolve,reject。只有resolve或者reject被调用,才会结束。

promise对象可以通过new创建, 结果返回后then和catch方法会调用,resolve和reject会走then方法,catch是捕捉未处理异常的方法(比如:500,404之类)。

值得注意的是,then方法的返回值为promise类型,如果在then中继续执行异步操作,则可以在then后面再次写一个then操作。叫做链式调用,例如:

  
Promise.resolve("success")
.then((res) => "异步操作")
.then((resSecond) => console.log(resSecond)); // resSecond为“异步操作”

另外可直接调用resolve状态或者reject状态,例如Promise.resolve(),或者Promise.reject()方法。这两个方法直接返回结果,也可以传入一个Promise对象或者工厂函数。这两个函数本质都是内部创建了一个Promise对象,调用resolve或者reject。

现如今很多的异步请求,异步执行方式,都在向promise靠拢。提供了很多的便利性。比如:axios,上面提到的fs模块,等等。我用过angular的subscribe,也是对异步的一种处理方式。但有点不伦不类。

1.1 模拟异步操作,用于测试

  
// 模拟异步请求
const suc = function (time: number) {
return new Promise(resolve => {
setTimeout(() => {
// time秒钟之后返回结果
resolve("success");
}, time);
})
} const rej = function (time: number) {
return new Promise((resolve, reject) => {
setTimeout(() => {
// time秒之后拒绝
reject("fail");
}, time);
})
}
// 以上代码也可合并为一个函数,请读者自行考虑。

1.2 Promise的all,race方法模拟

PromiseAll方法内内只接受两个异步Promise,算是简化版了(官网api代码简介),能力有限。PromiseRace基本和官网上的差不多。

PromiseRace: 竞争性关系,获取第一个结果(无论结果resolve或者reject),立即返回。

PromiseAll_2:感觉使用状态控制这种不是太好啊

  
// 准确来说,这个方法有缺陷,只要第一个返回,不管对与不对都返回,应该是所有结果都被reject掉才会返回reject,只有一个正确都要返回正确结果。可结合PromiseAll_2看
function PromiseRace(arrs: Array): Promise {
if (arrs.length === 0) return Promise.resolve([]); return new Promise((resolve, reject)=> {
arrs.forEach((pro) => {
Promise.resolve(pro).then(resolve, reject);
});
});
} // 当所有结果为ture,才会返回ture
function isAllFulfilled(states: Array): boolean {
let res: boolean = true;
states.forEach(state => res = res && state)
return res;
} // 用一种循环的方式迭代每个异步方法,如果不是函数或对象就直接作为结果返回
function PromiseAll_2(arrs: Array): Promise {
if (arrs.length === 0) return Promise.resolve([]);
const states: Array = Array.from({length: arrs.length}, (item) => item = false); return new Promise((resolve, reject)=> {
const result = [];
arrs.forEach((pro, index) => {
// 对输入做一个封装,如果是常数或者不是promise的这样就直接返回
Promise.resolve(pro).then(res => {
states[index] = true;
result[index] = res;
if (isAllFulfilled(states)) resolve(result);
}, err => reject(err));
});
});
} function PromiseAll(one: Promise, two: Promise): Promise {
return new Promise((resolve, reject) => {
let twoRes = null;
let oneRes = null;
// 基于两个异步互相检测,官网那个有点看不大明白。各位有什么好的代码建议不妨评论说一下
one.then((res) => {
oneRes = res;
if (twoRes) resolve([oneRes, twoRes]);
}, (err) => reject(err)); two.then((res) => {
twoRes = res;
if (oneRes) resolve([oneRes, twoRes]);
}, (err) => reject(err));
});
} PromiseAll(suc(1000), rej(2000)).then((res) => {
console.log(res);
}).catch((err) => console.log(err));

1.3 小工具。

  1. 使用promisify对settimeout做个封装,单纯只是延迟执行
  
const util = require("util");
// 封装settimeout延迟执行
const delay = util.promisify(setTimeout); // 用作延迟执行,一般在await的时候用 用例:
async function test() {
await delay(1000); // 延迟一秒执行
}
  1. async简单介绍
  async彻底解决了异步操作回调函数问题。
只需使用await关键字,就会等待异步操作执行完毕才会继续执行后续代码。把异步操作
变为同步操作。
// 代码
async function test() {
const { data } = await axios.get("http://www.baidu.com"); // { data }为解构赋值
// do something
} // 不用async
function test() {
axios.get("http://www.baidu.com").then((res) => {
console.log(res.data);
//do something
});
} // 对比以上结构,async函数的同步会带来很大的方便,但在加载网页的时候可能需要等待。
// 如果不希望页面卡顿,采用异步还是比较好的。

2. 每周分享

  1. 前端框架和es的一些变化,这里面介绍的是前端中最近的一些框架或者基础性知识。
  2. nginx的基础入门,对nginx的一个用法基本介绍。
  3. 阿里AI labs研发“智能防骚扰电话技术”,当接听到骚扰电话时,可以转到机器人接听。我试了一下,听得我一愣一愣的,还以为真的和人工客服聊天。具体想体验的可以在支付宝搜索天猫精灵。不过这项功能可能会给你带来困扰,如果你主动挂断电话,就会立马改为由智能机器人接听,如果是你女票打来的,你有事情马上挂断,后果不堪设想!好在可以关闭或者打开。玩玩可以,可不要贪杯啊。(>_<)

资料

对Promise的一些深入了解的更多相关文章

  1. Javascript - Promise学习笔记

    最近工作轻松了点,想起了以前总是看到的一个单词promise,于是耐心下来学习了一下.   一:Promise是什么?为什么会有这个东西? 首先说明,Promise是为了解决javascript异步编 ...

  2. 路由的Resolve机制(需要了解promise)

    angular的resovle机制,实际上是应用了promise,在进入特定的路由之前给我们一个做预处理的机会 1.在进入这个路由之前先懒加载对应的 .js $stateProvider .state ...

  3. angular2系列教程(七)Injectable、Promise、Interface、使用服务

    今天我们要讲的ng2的service这个概念,和ng1一样,service通常用于发送http请求,但其实你可以在里面封装任何你想封装的方法,有时候控制器之间的通讯也是依靠service来完成的,让我 ...

  4. 闲话Promise机制

    Promise的诞生与Javascript中异步编程息息相关,js中异步编程主要指的是setTimout/setInterval.DOM事件机制.ajax,通过传入回调函数实现控制反转.异步编程为js ...

  5. 深入理解jQuery、Angular、node中的Promise

    最初遇到Promise是在jQuery中,在jQuery1.5版本中引入了Deferred Object,这个异步队列模块用于实现异步任务和回调函数的解耦.为ajax模块.队列模块.ready事件提供 ...

  6. Promise的前世今生和妙用技巧

    浏览器事件模型和回调机制 JavaScript作为单线程运行于浏览器之中,这是每本JavaScript教科书中都会被提到的.同时出于对UI线程操作的安全性考虑,JavaScript和UI线程也处于同一 ...

  7. JavaScript进阶之路——认识和使用Promise,重构你的Js代码

    一转眼,这2015年上半年就过去了,差不多一个月没有写博客了,"罪过罪过"啊~~.进入了七月份,也就意味着我们上半年苦逼的单身生活结束了,从此刻起,我们要打起十二分的精神,开始下半 ...

  8. 细说Promise

    一.前言 JavaScript是单线程的,固,一次只能执行一个任务,当有一个任务耗时很长时,后面的任务就必须等待.那么,有什么办法,可以解决这类问题呢?(抛开WebWorker不谈),那就是让代码异步 ...

  9. 浅谈Angular的 $q, defer, promise

    浅谈Angular的 $q, defer, promise 时间 2016-01-13 00:28:00  博客园-原创精华区 原文  http://www.cnblogs.com/big-snow/ ...

  10. angular学习笔记(二十八-附2)-$http,$resource中的promise对象

    下面这种promise的用法,我从第一篇$http笔记到$resource笔记中,一直都有用到: HttpREST.factory('cardResource',function($resource) ...

随机推荐

  1. 第一次Java测试及感触

    周四进行了java测试,感触很深,测试的题目是用Java实现一个ATM机的管理系统.最后3个小时后,我没有完成这次测试,但是我找到了自己的很多不足,明确了自己的问题究竟在哪里. 关于这次测试我不会的最 ...

  2. 表达式语言 Expression Language

    JSP 2.0最重要的特性之一就是表达式语言 (EL),JSP用户可以用它来访问应用程序数据.由于 受到ECMAScript和XPath表达式语言的启发,EL也设计 成可以轻松地编写免脚本的JSP页面 ...

  3. laravel 中CSS 预编译语言 Sass 快速入门教程

    CSS 预编译语言概述 CSS 作为一门样式语言,语法简单,易于上手,但是由于不具备常规编程语言提供的变量.函数.继承等机制,因此很容易写出大量没有逻辑.难以复用和扩展的代码,在日常开发使用中,如果没 ...

  4. laravel 服务提供者

    服务提供者,在laravel里面,其实就是一个工厂类.它最大的作用就是用来进行服务绑定.当我们需要绑定一个或多个服务的时候,可以自定义一个服务提供者,然后把服务绑定的逻辑都放在该类的实现中.在lara ...

  5. java易错题----静态方法的调用

    class A{ public static String s="A.s"; } class B extends A{ public static String s="B ...

  6. hdu5758 思维,树形dp

    /*可以推测从叶子结点传送到叶子节点才能使传送次数最少,如果是偶数个叶子结点,那么传送leaf/2次就是答案,如果是奇数个叶子结点,则还有单独一条链需要覆盖dp[u]表示覆盖完u为根的子树需要走的边数 ...

  7. python接口自动化测试三十三:获取时间戳(10位和13位)

    很多时候,在调用接口时,需要对请求进行签名.需要用到unix时间戳. 在python里,在网上介绍的很多方法,得到的时间戳是10位.而java里默认是13位(milliseconds,毫秒级的). 下 ...

  8. 解决:sudo: pip: command not found

    1-问题:Ubuntu下执行sudo pip install package-name 出现 sudo: pip: command not found 的问题. 2-原因:编译sudo的时候加入了–w ...

  9. SVN项目迁移到Git上(并带有完整的提交记录)

    公司需求:早期的一些项目使用的是SVN,现在想要更换为Git,需要代码迁移并且能在Git上看到之前在SVN中的项目的提交记录,公司没有使用gitlab,代码都push在公司的服务器上,用的是Torto ...

  10. Docker相关释义

    Docker相关释义 基础网站:http://www.runoob.com/docker/docker-tutorial.html Docker的思想来自于集装箱,集装箱解决了什么问题?在一艘大船上, ...