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. 学习Apache(五)

     apache目前主要有两种模式:prefork模式和worker模式: 1)prefork模式(默认模式) prefork是Unix平台上的默认(缺省)MPM,使用多个子进程,每个子进程只有一个线程 ...

  2. python中PIL库的使用

    API参考 打开dos窗口,安装库: pip install pillow 很明显,图片有点大,咱们缩略一下: from PIL import Image im = Image.open(" ...

  3. 【译】感谢 Flash 所做的一切

    翻译:疯狂的技术宅来源:Chromium Blog原文标题:So long, and thanks for all the Flash英文原文:https://blog.chromium.org/20 ...

  4. 移动端城市定位,城市区域代码adcode

    使用高德定位API : AMap.Map('iCenter') AMap.CitySearch() 先在高德开放平台注册申请定位权限的key. 网站:高德开放平台 在需要定位的页面引入有定位key的s ...

  5. vue和react给我的感受

    以下纯属个人使用两个框架的感想和体会: 不知道你们是否有这种感觉~ 我vue和react都用过一段时间,但是vue给我感觉就是经常会忘记语法,需要对照文档才知道怎么写( 难不成是我没喝六个核桃的原因吗 ...

  6. 小程序拿checkbox的checked属性

     方法一.checkbox <checkbox class="round red" bindtap="checkboxChange" checked=&q ...

  7. FastAPI(六十七)实战开发《在线课程学习系统》接口开发--用户登陆接口开发

    接上一篇文章FastAPI(六十六)实战开发<在线课程学习系统>接口开发--用户注册接口开发.这次我们分享实际开发--用户登陆接口开发. 我们先来梳理下逻辑 1.查询用户是否存在2.校验密 ...

  8. Ubuntu系统报错The system is running in low-graphics mode

    Ubuntu系统报错:The system is running in low-graphics mode 我遇到过两次这种请况,这次解决了.很nice! 在csdn上搜到的大部分操作是: 鼠标进入系 ...

  9. Filebeat和logstash 使用过程中遇到的一些小问题记录

    一.filebeat 收集软链文件日志 1.1.场景 由于我们新部署的Nginx 日志都是采用的软链的形式. lrwxrwxrwx 1 root root 72 Apr 6 00:00 jy.baid ...

  10. cali1e4a9cee8dc这是什么东西?

    //我们查下k8s node节点,发现很多类似 cali7c620a7a67b 这样的类似网络设备的东西.//这些是什么呢?//k8s集群节点ht10,node网络情况.[root@ht10 cali ...