es6基础(2)--promise的深度解析

Promise已经深入到前端开发中的各个环节了,异步操作,api接口请求避免不了!Promise 是异步编程的一种解决方案,
比传统的解决方案——回调函数和事件——更合理和更强大!

es6基础(2)--promise的深度解析_第1张图片

promise实现红绿灯效果

const promise = new Promise((resolve, reject) => {
  if (true) {
    resolve("ok");
  }
});

promise.then((res) => {
  console.log(res);
});

function timeout(ms) {
  return new Promise((resolve, reject) => {
    //setTimeout第三个参数是第一个方法的参数
    setTimeout(resolve, ms, "done2222");
  });
}

timeout(1000).then((res) => {
  console.log(res, "res");
});

/**
 * ok
   done2222 res
 */

改成通用方法

function delay(ms, value) {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, ms, value);
  });
}

async function showColor() {
  const res1 = await delay(1000, "红灯");
  console.log(res1);
  const res2 = await delay(2000, "黄灯");
  console.log(res2);
  const res3 = await delay(3000, "绿灯");
  console.log(res3);
  // showColor();
}

showColor();

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

let promise = new Promise((resolve, reject) => {
  console.log("Promise");
  resolve();
});

promise.then(() => {
  console.log("resolved");
});

console.log("HI");

/**
 * Promise
 * HI
 * resolved
 */

function loadImageAsync(url) {
  return new Promise((resolve, reject) => {
    const image = new Image();
    image.onload = function () {
      resolve(image);
    };
    image.onerror = function () {
      reject(new Error("Could not load image at " + url));
    };
    image.src = url;
  });
}

封装原生ajax

const getJSON = function (url) {
  const promise = new Promise((resolve, reject) => {
    const handler = function (data) {
      if (this.readyState != 4) return;
      if (this.status === 200 && this.readyState === 4) {
        //console.log(this, "8888");
        resolve(this.response);
      } else {
        reject(new Error(this.statusText));
      }
    };
    const client = new XMLHttpRequest();
    client.open("get", url);
    client.onreadystatechange = handler;
    client.responseType = "json";
    client.setRequestHeader("Accept", "application/json");
    client.send();
  });
  return promise;
};

Promise中返回一个promise

const p1 = new Promise((resolve, reject) => {
  setTimeout(reject, 2000, new Error("fail"));
});

const p2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 2000, p1);
});

p2.then((res) => console.log(res)).catch((error) => {
  console.log(error);
});
//(node:24044) UnhandledPromiseRejectionWarning: Error: fail
//浏览器中 => Error: fail

.catch方法的作用与优势

new Promise((resolve, reject) => {
  return resolve(1);
  console.log(2);
}).then((res) => {
  console.log(res);
});

const getJSON = function (url) {
  const promise = new Promise((resolve, reject) => {
    const handler = function (data) {
      if (this.readyState != 4) return;
      if (this.status === 200 && this.readyState === 4) {
        console.log(this, "8888");
        resolve(this.response);
      } else {
        reject(new Error(this.statusText));
      }
    };
    const client = new XMLHttpRequest();
    client.open("get", url);
    client.onreadystatechange = handler;
    client.responseType = "json";
    client.setRequestHeader("Accept", "application/json");
    client.send();
  });
  return promise;
};

getJSON("./data.json")
  .then((res) => {
    return getJSON(res.url);
  })
  .then(
    (data) => {
      throw new Error("fail22");
      console.log(data, "data");
    },
    (err) => console.log("rejected", err)
  );
.catch((err) => console.log("rejected2222", err));

getJSON("./data.json")
  .then((res) => {
    throw new Error("fail22");
    return getJSON(res.url);
  })
  .then((data) => {
    console.log(data, "data");
  })
  .catch((err) => console.log("rejected", err));

const datas = [1, 2, 3].map((ele) => {
  return getJSON("./data" + ele + ".json");
});
// console.log(datas, "data");
Promise.all(datas)
  .then((res) => {
    console.log(res, "datas");
  })
  .catch((err) => {
    console.log(err, "catch");
  });

/**
 * promises是包含 3 个 Promise 实例的数组,只有这 3 个实例的状态都变成fulfilled,
 * 或者其中有一个变为rejected,才会调用Promise.all方法后面的回调函数。
 */

promise.all的使用与特性

const p1 = new Promise((resolve, reject) => {
  resolve("hello");
})
  .then((res) => res)
  .catch((value) => value);

const p2 = new Promise((resolve, reject) => {
  throw new Error("报错了");
})
  .then((res) => res)
  .catch((value) => value);

Promise.all([p1, p2])
  .then((res) => console.log(res))
  .catch((e) => console.log(e));

promise实现异步加载图片

<div id="box"></div>
   <script>
    //加载一张图片
    loadImageAsync(
  "https://triassit.oss-cn-shenzhen.aliyuncs.com/1502096626409238530/form/1669167445413228545/40c94992-3f2b-42e6-9b90-0dc8cb08579e/76933eb2-9aae-4ed2-bb6a-b56be4224a1d.jpg?Expires=1689737677&OSSAccessKeyId=LTAI5tEA4v7LMXeCfNXXikQq&Signature=I2Rtb%2BmGzw2ESi%2BM6yQ%2F5kZ65RA%3D&response-content-disposition=attachment"
  ).then((res) => {
    console.log(res, "loadImageAsync");
    // document.querySelector('#box').appendChild(res)
  });
  //加载多张图片
  const imgUrls = ["https://triassit.oss-cn-shenzhen.aliyuncs.com/1502096626409238530/form/1669167445413228545/40c94992-3f2b-42e6-9b90-0dc8cb08579e/76933eb2-9aae-4ed2-bb6a-b56be4224a1d.jpg?Expires=1689737677&OSSAccessKeyId=LTAI5tEA4v7LMXeCfNXXikQq&Signature=I2Rtb%2BmGzw2ESi%2BM6yQ%2F5kZ65RA%3D&response-content-disposition=attachment",
  "https://triassit.oss-cn-shenzhen.aliyuncs.com/1502096626409238530/form/1669167445413228545/40c94992-3f2b-42e6-9b90-0dc8cb08579e/381ffe18-0d10-452b-93a8-07b4b1f4f8e1.jpg?Expires=1689737677&OSSAccessKeyId=LTAI5tEA4v7LMXeCfNXXikQq&Signature=k55etNrEXifvOXAxWpsJnjZnZak%3D&response-content-disposition=attachment"]
  const arrs = imgUrls.map(async url => {
    return await loadImageAsync(url)
  })

  // console.log(arrs)

  const ret = Promise.all(arrs)

  // console.log(ret,'Promise')
  ret.then(res => {
    console.log(res,'Promise')
    res.forEach(item => document.querySelector('#box').appendChild(item))
  })

几个请求的json数据

data1.json

{
  "name":"好好好",
  "age":100,
  "url":"data2.json"
}

data2.json

{
  "addr":"广州"
}

data3.json

{
  "sex":"男"
}

你可能感兴趣的:(es6系列精读,es6,前端,ecmascript)