分享

ES6 promise

 Coder编程 2020-08-15

回调与promise
方法 用于请求数据(模拟)
resolve代表成功时要做的事情

    function f() {
        return new Promise(resolve => {
            setTimeout(function() {
                resolve();
            }, 1000);
        })
    }

    f()
        .then(function() {
            console.log(1);
            //return promise实例,才能继续.then()
            return f();
        })
        .then(function() {
            console.log(2);
            return f();
        })
        .then(function() {
            console.log(4);
            return f();
        })
        .then(function() {
            console.log(3);
            return f();
        })
        .then(function() {
            console.log(5);
            return f();
        })
        .then(function() {
            console.log(6);
        });

案例:
Promise 新建后立即执行,所以首先输出的是Promise,然后,then方法指定的回调函数,将在当前脚本所有同步任务执行完才会执行,所以resolved最后输出

    let promise=new Promise(resolve=>{
        console.log('Promise');
        resolve();
    });

    promise.then(function(){
        console.log('resolved');
    });

    console.log('Hello!');
    //结果:Promise Hello! resolved

Promise小动画案例:
index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    #el {
      width: 100px;
      background: green;
      transition: all 1s;
      color: white;
      line-height: 100px;
      text-align: center;
      font-size: 40px;
    }
  </style>
</head>
<body>
  <div id="el"></div>
  <button id="btn">开始</button>
  <script src="./main.js"></script>
</body>
</html>

main.js

function moveTo(el, x, y) {
    return new Promise(resolve => {
        el.style.transform = `translate(${x}px, ${y}px)`;
        setTimeout(function() {
            resolve();
        }, 1000);
    });
}

let el = document.querySelector('div');

document.querySelector('button').addEventListener('click', e => {
    moveTo(el, 100, 100)
        .then(function() {
            console.log('第一次移动');
            return moveTo(el, 200, 200);
        })
        .then(function() {
            console.log('第二次移动');
        })
        .then(function() {
            console.log('第二次移动');
        });
});

错误处理
resolve成功时操作
reject失败时操作

  function f(val) {
    return new Promise((resolve, reject) => {
      if (val) {
        resolve({ name: '小明' });
      } else {
        reject('404');
      }
    }); 
  }

  f(true)
    .then((data) => {
      console.log(data)
    }, e => {
      console.log(e);
    })

catch
使用实例的catch方法 可以捕获错误

    f(true)
      .then(data => {
        console.log(data);
        return f(false);
      })
      .then(() => {
        console.log('我永远不会被输出');
      })
      .then(() => {

      })
      .catch(e => {
        console.log(e);
        return f(false) ;
      });

finally
不论成功还是失败 finally中的内容一定会执行

   f(true)
      .then(data => {
        console.log(data);
        return f(false);
      })
      .catch(e => {
        console.log(e);
        return f(false);
      })
      .finally(() => {
        console.log(100);
      });

promise三种状态
pending 进行中
fulfilled 成功
rejected 失败
状态的改变不可逆:
pending可以到fulfilled或者rejected


 

Promise.all方法可以把多个promise实例 包装成一个新的promise实例
Promise.all([ promise1, promise2 ]) : Promise
模拟需要多个请求的数据 才能进行下一步操作的情况

    function getData1() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log('第一条数据加载成功');
          resolve('data1');
        }, 1000);
      });
    }
    function getData2() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log('第二条数据加载成功');
          resolve('data2');
        }, 1000);
      });
    }
    function getData3() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log('第三条数据加载成功');
          resolve('data3');
        }, 1000);
      });
    }
    function getData4() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log('第四条数据加载成功');
          resolve('data4');
        }, 2000);
      });
    }
    // 所有数据都成功,则总决议成功,并返回所有成功提示
    let p = Promise.all([getData1(),getData2(),getData3(),getData4()]);
    p.then(arr => {
      console.log(arr);
    });

一条数据失败,则总决议失败,并返回错误信息

    function getData1() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log('第一条数据加载成功');
          resolve('data1');
        }, 1000);
      });
    }
    function getData2() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log('第二条数据加载成功');
          resolve('data2');
        }, 1000);
      });
    }
    function getData3() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log('第三条数据加载成功');
          resolve('data3');
        }, 1000);
      });
    }
    function getData4() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          reject('data4 err');
        }, 500);
      });
    }
    // 一条数据失败,则总决议失败,并返回错误信息
    let p = Promise.all([getData1(),getData2(),getData3(),getData4()]);
    p.then(arr => {
      console.log(arr);
    },e=>{
        console.log(e);
    });

空数组直接决议为成功

    function getData1() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log('第一条数据加载成功');
          resolve('data1');
        }, 1000);
      });
    }
    function getData2() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log('第二条数据加载成功');
          resolve('data2');
        }, 1000);
      });
    }
    function getData3() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log('第三条数据加载成功');
          resolve('data3');
        }, 1000);
      });
    }
    function getData4() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          reject('data4 err');
        }, 500);
      });
    }
    // 空数组直接决议为成功
    let p = Promise.all([]);
    p.then(() => {
      console.log('null');
    },e=>{
        console.log(e);
    });

promise.race
只要有一个决议为成功或者失败,就会返回

  function getData1() {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        console.log('第一条数据加载成功');
        reject('err');
      }, 500);
    });
  }
  function getData2() {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        console.log('第二条数据加载成功');
        resolve('data2');
      }, 1000);
    });
  }
  function getData3() {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        console.log('第三条数据加载成功');
        resolve('data3');
      }, 1000);
    });
  }

  let p = Promise.race([getData1(),getData2(),getData3()]);

  p.then(data => {
      console.log(data);
  }, e => {
      console.log(e);
  })

空数组会被挂起

  let p = Promise.race([]);

Promise.resolve() 和 Promise.reject()
常用来生成已经被决议为失败或者成功的promise实例


 

Promise.resolve传递一个普通的值
决议成功并把值传递过去

    let p1 = new Promise(resolve => {
      resolve('成功!');
    });
    let p2 = Promise.resolve('成功!');

Promise.resolve传递一个promise实例

    let poruomiesi = new Promise(resolve => {
      resolve('耶!')
    });
    // 直接返回传递进去的promise
    let p = Promise.resolve(poruomiesi);
    p.then(data => void console.log(data));
    console.log(p === poruomiesi); 

Promise.resolve传递一个thenable
如果传递的是个thenable

    let obj = {
      then(cb) {
        console.log('我被执行了');
        cb('哼!');
      },
      oth() {
        console.log('我被抛弃了');
      }
    }
    // 立即执行then方法
    Promise.resolve(obj).then(data => {
      console.log(data);
    });

Promise.reject
直接决议为失败,不做处理

    Promise.reject({ then() { console.log(1) } })
      .then(() => {
        console.log('我不会被执行');
      }, e => {
        console.log(e);
      });

异步任务总是在同步任务之后执行
把同步的任务转成异步任务

    function createAsyncTask(syncTask) {
      return Promise.resolve(syncTask).then(syncTask => syncTask());
    }
    createAsyncTask(() => {
      console.log('我变成了异步任务!!!');
      return 1 + 1;
    }).then(res => {
      console.log(res);
    });
    console.log('我是同步任务!');

要求:多张图片加载完之后才能进行统一展示

    const loadImg = src => {
        return new Promise((resolve, reject) => {
            const img = new Image();
            img.src = src;
            img.onload=()=>{
                resolve(img);
            };
            img.onerror=(e)=>{
                reject(e);
            };
            // img.onload = void resolve(img);
            // img.onerror = void reject('加载失败');
        });
    };

    const imgs = [
        'http://img1.sycdn.imooc.com\/climg/5b16558d00011ed506000338.jpg',
        'http://img1.sycdn.imooc.com\/climg/5b165603000146ca06000338.jpg',
        'http://img1.sycdn.imooc.com//climg/5b1656140001c89906000338.jpg'
    ];

    // map遍历数组中的每一项
    Promise.all(imgs.map(src => loadImg(src))).then(arr => {
        console.log(arr);
        arr.forEach((img)=>{
            document.body.appendChild(img);
        });
    });
    // map遍历数组中的每一项(与上面相同作用,上面是简写)
    // map进行循环,每循环一次就将src作为参数传递进来
    // const promises=imgs.map(src =>{
    //     return loadImg(src);
    // });
    // Promise.all(promises).then(arr => {
    //     console.log(arr);
    //     arr.forEach((img)=>{
    //         document.body.appendChild(img);
    //     });
    // }).catch((e)=>{
    //     console.log(e);
    // });

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多