Hibop / Hibop.github.io

Hibop 个人博客
https://hibop.github.io/
23 stars 1 forks source link

关于异步——promise #12

Open Hibop opened 6 years ago

Hibop commented 6 years ago

异步操作:

Promise挂载的方法

三种状态

并发Promise

串行Promise

几个等价用法

then(resolveHandler, rejectHandler)中的rejectHandler不会捕获resolveHandler中的错误, 只会捕获then前面的错误, 而catch是捕获整个链路的错误,故推荐使用catch

promise穿透现象

then(fn) fn如果返回才可以传递到下一个then, 否则fn不为函数或者返回null undefined 下一个then会接收上一个的return值

Promise.resolve('foo').then(Promise.resolve('bar')).then(function (result) {
  console.log(result); // 'foo' 不是‘bar’
});

promise链式调用: 调用队列实现

Promise.resolve().then(fetch1).then(fetch1);

可以使用更优雅的函数式方式

[fetch1, fetch1].reduce((p, f) => p.then(f), Promise.resolve())

或者更加函数话封装成函数

let composeAsync = (...funcs) => x => funcs.reduce(applyAsync, Promise.resolve(x));

通过composition pipeline传入的初始值(可以为同步或者异步),保证顺序执行

let transformData = composeAsync(func1, asyncFunc1, asyncFunc2, func2);
transformData(data);

ECMAScript 2017标准中, 串行组合可以通过使用async/await而变得更简单:

for (let f of [func1, func2]) {
  await f();
}

async await

最后来个小测试巩固下

console.log('0.outer');

// setTimeout有个最小执行时间(minimum delay of 4ms ),并不是0s执行的
setTimeout(() => {
  console.log('1.setTimeout')
}, 0);

new Promise((resolve, reject) => {
  console.log('2.promise before resolve');

  for(var i=0; i < 10000; i++) {
    if(i === 10) {console.log('3.promise')}
    i === 9999 && resolve();
  }

  console.log('4.promise after resolve');
}).then(() => {
  console.log('5.then');
}).then(() => {
  throw new Error('Something failed');
  console.log('5.1.then error');
}).then(() => {
  console.log('5.2.then after error');
}).catch(() => {
  console.log('5.3. catch');
}).then(() => {
  console.log('5.4. after catch then');
}).finally(() => {
  console.log('5.5. finally');
})

console.log('6.outer');
Hibop commented 6 years ago
Hibop commented 4 years ago

常见问题汇总

  1. 异步顺序

    const promise = new Promise((resolve, reject) => {
    console.log(1);
    resolve();
    console.log(2);
    });
    promise.then(() => {
    console.log(3);
    });
    console.log(4);

    result: 1,2,4,3

  2. Promise状态一旦改变,无法在发生变更

    
    const promise = new Promise((resolve, reject) => {
    setTimeout(() => {
    resolve('success')
    reject('error')
    }, 1000)
    })
    promise.then((res)=>{
    console.log(res)
    },(err)=>{
    console.log(err)
    })
reslut: success

3. 传值穿透
```js
Promise.resolve(1)
  .then(2)
  .then(Promise.resolve(3))
  .then(console.log)

result: 1

  1. 先微任务后宏任务
    
    setTimeout(()=>{
    console.log('setTimeout')
    })
    let p1 = new Promise((resolve)=>{
    console.log('Promise1')
    resolve('Promise2')
    })
    p1.then((res)=>{
    console.log(res)
    })
    console.log(1)

result: Promise1   1   Promise2    setTimeout