Promise是什么:

Promise是异步微任务(process.nextTick、Promise.then() catch() finally()等),用于解决异步多层嵌套回调的问题(回调地狱--小球做正方形路径运动),让代码的可读性更高、更容易维护

Promise使用:

Promise是ES6提供的一个构造函数,可以使用Promise构造函数new出一个实例,Promise构造函数接受一个函数作为参数这个函数有两个参数,分别是resolvereject

resolve将Promise的状态由等待变为成功(resolved),将异步操作的结果作为参数传递出去;

reject将Promise的状态变为失败(rejected),在异步操作失败时调用,将异步操作报错的错误作为参数传递过去。

实例创建完成后,可以使用then方法分别指定成功或者失败的回调回调函数,也可以使用catch捕获失败,then和catch最终返回的也是一个Promise,所以可以链式调用

Promise的特点:

1.对象状态不受外界影响(Promise对象代表一个异步操作,有三种状态) - pending(等待状态) - resolved(成功状态) - rejected(失败状态)

2.一旦状态改变,就不会再变化,任何时候都可以得到这个结果Promise对象状态的改变只有两种可能,

pending => resolved (then第一个回调)和 pending => rejected(then第二个回调)

(这两个状态为结束状态,表示Promise的生命周期已结束)

3.resolve方法中的参数是then中回调函数的参数,reject方法中的参数是catch中的参数

4.then方法和catch方法返回的都是成功状态的Promise(catch中throw返回失败状态的Promise)

Promise的其他方法:

Promise.finally():当promise状态发生变化时执行(任何变化都执行),不变化不执行

Promise.resolve(value):返回成功状态的Promise对象,并将value转递给对应的then方法

(当resolve函数接收的是promise对象时,后面的then会根据传递的promise对象的状态变化决定执行哪一个回调)

Promise.reject():返回一个失败状态的Promise对象,并将给定的失败信息传递给对应的处理方法

Promise.any():接受一个promise对象集合,当其中的第一个promise成功时,就返回那个成功的promise值,不会等待其他promise全部完成

Promise.all():返回一个新的promise对象,该promise对象在参数对象里接收多个promise对象,参数中的promise都成功时才会触发成功,任意一个promise对象失败都会触发失败

Promise.race():使用第一个返回的promise实例对象,成功就是成功,失败就是失败

Promise.allSettled():该方法的状态无传入promise的状态无关,它永远都是成功的,只会记录下各个promise的表现

(Promise.all、Promise.race、Promise.allSettled传入的若不是promise数组,会将其转换成promise数组,任何可遍历对象都可作为数组)

async/await:

async/await是基于Promise实现的,使得异步代码看起来像同步代码,是写异步代码的新方式

async/await实际上是Generator的语法糖。顾名思义,async关键字,代表后面的函数中有异步操作,await表示等待一个异步方法执行完成

声明异步函数只要在普通函数前加上一个关键字async即可

async函数返回一个Promise对象,(若返回值不是Promise对象也会通过Promise.resolve() 封装成 Promise 对象返回)因此async函数return返回的值可以通过then方法来接收

async function funcA() {
return 'hello!';
} funcA().then(value => {
console.log(value);
})
// hello!

await就是异步等待,等待的是一个Promise,因此await后面应该是一个Promise对象,若不是,也会被转成立即resolve的Promise

async函数被调用后就会开始执行,遇到await后就会等待其后面的异步操作执行完成,接着执行函数体后面的语句

总的来说:async函数调用不会造成代码的阻塞,但是await会造成async函数内部代码的阻塞

async function func() {
console.log('async function is running!');
const num1 = await 200;
console.log(`num1 is ${num1}`);
const num2 = await num1+ 100;
console.log(`num2 is ${num2}`);
const num3 = await num2 + 100;
console.log(`num3 is ${num3}`);
} func();
console.log('run me before await!');
// async function is running!
// run me before await!
// num1 is 200
// num2 is 300
// num3 is 400

func函数执行后先输出了  ‘async function is running!’,接着遇到了await异步等待,函数返回执行后面的同步任务 'run me before await!'

同步执行完成后接着await等待的位置继续执行。

可以说:async函数可以看作多个异步任务包装成一个Promise对象,而await命令就是其内部的语法糖

await后面的Promise对象不会总是返回resolved状态,只要一个await后面的Promsie状态变成rejected,整个async都会中断执行

为了避免此情况可以使用try...catch来封装多个await:

async function func() {
try {
const num1 = await 200;
console.log(`num1 is ${num1}`);
const num2 = await Promise.reject('num2 is wrong!');
console.log(`num2 is ${num2}`);
const num3 = await num2 + 100;
console.log(`num3 is ${num3}`);
} catch (error) {
console.log(error);
}
} func();
// num1 is 200
// 出错了
// num2 is wrong!

async/await:使得异步代码看起来像同步代码

function sayHi(name) {
return new Promise((resolved, rejected) => {
setTimeout(() => {
resolved(name);
}, 2000)
})
} async function sayHi_async(name) {
const sayHi_1 = await sayHi(name)
console.log(`你好, ${sayHi_1}`)
const sayHi_2 = await sayHi('李四')
console.log(`你好, ${sayHi_2}`)
const sayHi_3 = await sayHi('王二麻子')
console.log(`你好, ${sayHi_3}`)
} sayHi_async('张三')
// 你好, 张三
// 你好, 李四
// 你好, 王二麻子

Generator:

generator(生成器)是ES6标准引入的新的数据类型。一个generator看起来像个函数,但可以返回多次。

ES6定义的generator是借鉴了python中的generator概念和语法

函数的概念:一个函数是一段完整的代码,调用一个函数就是传入函数,然后返回结果

函数在执行的过程中,如果没有遇到return语句(没有return,就是隐含return undefined),控制权无法交回给被调用的代码

function foo(x) {
return x + x;
} var r = foo(1); // 调用foo函数

而generator定义如下:

function* foo(x) {
yield x + 1;
yield x + 2;
return x + 3;
}

generator由 function* 定义,并且除了return语句外可以通过 yield 返回多次

举个例子:斐波那契数列

function* fib(max) {
var
t,
a = 0,
b = 1,
n = 0;
while (n < max) {
yield a;
[a, b] = [b, a + b];
n ++;
}
return;
}

调用generator和函数不同,有两种调用方法,一是调用generator的 next() 方法:

var f = fib(5);
f.next(); // {value: 0, done: false}
f.next(); // {value: 1, done: false}
f.next(); // {value: 1, done: false}
f.next(); // {value: 2, done: false}
f.next(); // {value: 3, done: false}
f.next(); // {value: undefined, done: true}

next()方法会执行generator代码,每次遇到 yield a;就会返回一个对象{value: a, done: false}。每次返回的value就是yield的返回值,done表示这个generator是否已经执行结束

二是直接使用 for...of 循环迭代generator

for (var x of fib(10)) {
console.log(x); // 依次输出0, 1, 1, 2, 3, ...
}

generator的用处:

由于generator在执行的过程中可以返回多次,所以他看上去像一个可以记住执行状态的函数,利用这一点,通过generator可以实现需要用面向对象才能实现的功能

generator还可以把异步代码变成 “同步” 代码

try {
r1 = yield ajax('http://url-1', data1);
r2 = yield ajax('http://url-2', data2);
r3 = yield ajax('http://url-3', data3);
success(r3);
}
catch (err) {
handle(err);
}

new关键字的执行过程:(构造函数为Func)

  • 创建一个空对象,并将该空对象继承Func.prototype
  • 执行构造函数,并将this指向刚刚创建的新对象
  • 返回新对象

参考:

https://segmentfault.com/a/1190000015488033

https://www.liaoxuefeng.com/wiki/1022910821149312/1023024381818112#0

Promise与async/await与Generator的更多相关文章

  1. callback vs async.js vs promise vs async / await

    需求: A.依次读取 A|B|C 三个文件,如果有失败,则立即终止. B.同时读取 A|B|C 三个文件,如果有失败,则立即终止. 一.callback 需求A: let read = functio ...

  2. Promise和async await详解

    本文转载自Promise和async await详解 Promise 状态 pending: 初始状态, 非 fulfilled 或 rejected. fulfilled: 成功的操作. rejec ...

  3. node.js异步控制流程 回调,事件,promise和async/await

    写这个问题是因为最近看到一些初学者用回调用的不亦乐乎,最后代码左调来又调去很不直观. 首先上结论:推荐使用async/await或者co/yield,其次是promise,再次是事件,回调不要使用. ...

  4. 异步操作之 Promise 和 Async await 用法进阶

    ES6 提供的 Promise 方法和 ES7 提供的 Async/Await 语法糖都可以更好解决多层回调问题, 详细用法可参考:https://www.cnblogs.com/cckui/p/99 ...

  5. Promise及Async/Await

      一.为什么有Async/Await? 我们都知道已经有了Promise的解决方案了,为什么还要ES7提出新的Async/Await标准呢? 答案其实也显而易见:Promise虽然跳出了异步嵌套的怪 ...

  6. Callback, Promise和Async/Await的对比

    Callback, Promise和Async/Await的对比 Callback Hell getData1(function (data1) { console.log('我得到data1了') ...

  7. 异步Promise及Async/Await最完整入门攻略

    一.为什么有Async/Await? 我们都知道已经有了Promise的解决方案了,为什么还要ES7提出新的Async/Await标准呢? 答案其实也显而易见:Promise虽然跳出了异步嵌套的怪圈, ...

  8. “setTimeout、Promise、Async/Await 的区别”题目解析和扩展

    解答这个题目之前,先回顾下JavaScript的事件循环(Event Loop). JavaScript的事件循环 事件循环(Event Loop):同步和异步任务分别进入不同的执行"场所& ...

  9. promise 进阶 —— async / await 结合 bluebird

    一.背景 1.Node.js 异步控制 在之前写的 callback vs async.js vs promise vs async / await 里,我介绍了 ES6 的 promise 和 ES ...

随机推荐

  1. 转:为什么数据库选B-tree或B+tree而不是二叉树作为索引结构

    转载至:https://blog.csdn.net/sinat_27602945/article/details/80118362 B-Tree就是我们常说的B树,一定不要读成B减树,否则就很丢人了. ...

  2. 什么是 Spring 引导的执行器?

    Spring Boot 执行程序提供了 restful Web 服务,以访问生产环境中运行应用程序 的当前状态.在执行器的帮助下,您可以检查各种指标并监控您的应用程序.

  3. 客户端回调 Watcher?

    客户端 SendThread 线程接收事件通知,交由 EventThread 线程回调 Watcher. 客户端的 Watcher 机制同样是一次性的,一旦被触发后,该 Watcher 就失效了.

  4. hadoop 分布式系统与Hadoop MapReduce

    Hadoop分为两部分 Hadoop MapReduce和Hadoop分布式文件系统 1分布式系统由Master Node 和多台 slave Node组成. 1.1MasterNode Master ...

  5. 关于elementUI如何在表格循环列表里分别新增Tag的设计使用

    话不多说,直接上代码.想要实现的目的是这样的,想要在表格里单独添加每一个tag 那么,需要解决的问题就是如何定义这每一个插槽里的输入框,把每个输入框以及里面插入的数据区分开. 研究了很久,最后选择了对 ...

  6. visual studio 2019工具里添加开发中命令提示符的方法

    最新新装了visual studio 2019,发现默认的没有开发者命令提示符 现将添加步骤描述如下: 从VS2019菜单选择"Tools",然后选择"外部工具" ...

  7. 7_根轨迹_Part1_“根”的作用

    这里的渐近线,应该是e^[**wn]/wd,忘记除wd了

  8. 百度开放云 BOS Uploader

    百度开放云 BOS Uploader bce-bos-uploader 是基于 bce-sdk-js 开发的一个 ui 组件,易用性更好.DEMO地址是:http://leeight.github.i ...

  9. 数据库number(4,3)表示什么

    1 你看 number(4,3)是表示 这个数 一共有4位是有效位,后面的3 表示有3个是小数也就是这个数 只能是1.234,这样格式的 最大只能是9.999,2 number(3,4) 表示这个数 ...

  10. 利用css3渐变效果实现圆环旋转效果

    * { margin: 0; padding: 0; } .stage { width: 200px; height: 130px; margin: 100px auto; position: rel ...