ES6之Promise进修

初识Promise

Promise对象是一个组织函数,其吸收一个函数作为参数,resolvereject为这个函数的参数,函数内部平常为异步实行的代码,resolve作为异步实行完成以后胜利的回调,reject作为异步实行抛错的回调。Promise组织函数能够理解为实行异步的历程,其resolvereject为实行异步挪用效果的回调函数。

《ES6之Promise进修》

// 代码1
var p = new Promise((resolve, reject) => {
  // 实行一系列的异步实行
  // some codes...
  if (true) {
    resolve("异步实行胜利");
  } else {
    reject("异步实行抛错");
  }
}); // fulfilled: 异步实行胜利 ; 非fulfilled: 异步实行抛错

Promise的异步处置惩罚

then和catch的运用

Promise组织函数返回一个异步实行以后的promise对象,该对象对异步的效果进一步处置惩罚。

// 代码2
p
  .then((res) => {
    // try catch 手动抛错
    try {
      // console.log("异步返回胜利状况");
      throw Error("毛病代码");
    } catch(e) {
      console.log("实行catch");
      return Promise.reject(e);
    }
  })
  .catch((res) => {
    console.log(res); // 输出上一个 then 中 catch 的 e
    return "这里由毛病信息过去的数据";
  })
  .then((res) => {
    console.log(res); // 若上一个catch实行,输出:这里由毛病信息过去的数据
  })

以上代码实行效果:

# 效果1
实行catch
Error: 毛病代码
    at p.then (**/promise.js:77:10)
    at process._tickCallback (internal/process/next_tick.js:109:7)
    at Module.runMain (module.js:607:11)
    at run (bootstrap_node.js:423:7)
    at startup (bootstrap_node.js:147:9)
    at bootstrap_node.js:538:3
这里由毛病信息过去的数据

promise对象的链式挪用

代码2能够看出,promise对象状况为resolve的时刻,实行then要领,而且在不抛错状况下会延续实行链式挪用的then要领,若then要领抛出非常或许抛出返回Promise.reject()要领,会转到实行catch要领,若catch要领返回的不是Promise.reject()要领或许不抛出非常,则一切运用return返回的数据都邑作为参数传给下一个then函数参数的参数,即代码2中的末了一个then要领指定函数参数的res是上一个catchreturn的数据。

var p = new Promise((resolve, reject) => {
  resolve("ok");
});
p.then((msg) => {
  console.log(msg);
  return Promise.reject("then01抛错");
}).catch((errMsg) => {
  console.warn(errMsg);
}).then(() => {
  console.log("then02再实行");
}).then(() => {
  console.log("then03再实行");
  return Promise.reject("then03抛错");
}).catch((errMsg) => {
  console.warn(errMsg);
  return "catch02 return 给下一个then指定要领的值";
}).then((msg) => {
  console.log(msg);
});

运转效果以下:

《ES6之Promise进修》

这是因为then要领和catch要领返回的都是一个promise对象。then要领指定的回调函数抛出毛病会被下一个catch要领捕捉,多个then要领实行也是云云。catch要领会捕捉上一个catch要领(如果有的话)以后抛错的毛病。

《ES6之Promise进修》

换言之,无论是then要领照样catch要领,返回的都是一个promise对象,其状况取决于上一个要领指定的函数是不是顺遂实行或许没有返回Promise.reject()

Promise状况

一旦Promise的状况变成resolved或许rejected,就会永远坚持该状况,不会再变。

var p = new Promise((resolve, reject) => {
  resolve("ok");
  throw new Error("wrong");
});
p.then((msg) => {
  console.log(msg);
}).catch((errMsg) => {
  console.warn(errMsg);
});

// ok

在Promise的参数函数中,因为先判断了resolved状况,所以在以后只会实行then函数,背面抛出的毛病会即是没抛出来。

别的,“事宜轮回”会对抛出的效果有影响。

var p = new Promise((resolve, reject) => {
  resolve("ok");
  setTimeout(() => {
    throw new Error("wrong");
  }, 0);
});
p.then((msg) => {
  console.log(msg);
}).catch((errMsg) => {
  console.warn(errMsg);
});

// ok

// 浏览器抛出的毛病
// index.js:4 Uncaught Error: wrong
//    at setTimeout (index.js:4)
// setTimeout    @    index.js:4

在本轮“事宜轮回”中,promise对象p先实行,所以组织函数Promise的指定函数先输出‘ok’;在进入到下一次的“事宜轮回”的时刻,因为Promise函数体已实行终了,故背面抛出的毛病是在Promise函数体外抛出的,Promise函数体没法捕捉到这个毛病。

Promise.resolve()

Promise.resolve()吸收一个参数,其返回一个promise对象的状况会因为传入的参数的差别而差别。

参数离别以下几种状况:

返回一个状况为resolved的promise对象,也就是下一步会实行then要领。

var p = Promise.resolve();

p.then((res) => {
  console.log("then");
}).catch((res) => {
  console.log("catch");
});

// then
  • thenable对象

var thenable = {
  then: function (resolve, reject) {
    console.log("马上实行thenable的then的要领" + Date.now());
    resolve("判断以后的信息");
  }
}

var p = Promise.resolve(thenable);

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

// 马上实行thenable的then的要领1494485393447
// 判断以后的信息

// 相当于

var p = new Promise(function (resolve, reject) {
  console.log("马上实行thenable的then的要领" + Date.now());
  resolve("判断以后的信息");
});

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

// 马上实行thenable的then的要领1494485454503
// 判断以后的信息

thenable对象作为参数,在实行Promise.resolve(thenable)要领的时刻,会马上实行thenable对象中的then要领,而且其返回的Promise对象的状况取决于thenable对象的then要领实行的是resolve()照样reject()。这类状况下,就相当于Promise组织函数以thenable对象的then要领作为参数,实例化一个Promise实例。

  • 一个非Promise对象,且不含有then要领的对象——非thenable对象

var p = Promise.resolve({
  a: 1
});
p.then((res) => {
  console.log(res);
});

// { a: 1 }

var p01 = Promise.resolve('Hello Promise!');
p01.then((res) => {
  console.log(res);
});

// Hello Promise!

这类状况下,Promise.resolve()的状况为resolved,其吸收的参数会作为then要领指定函数的参数。

  • Promise对象

var p01 = new Promise((resolve, reject) => {
  reject('Throw some error! Come on! You bite me.');
});

var p = Promise.resolve(p01);

p.then((res) => {
  console.log("这是then要领");
}).catch((errMsg) => {
  console.log(errMsg);
});

// Throw some error! Come on! You bite me.

传入的是一个Promise对象,Promise.resolve()返回的对象的状况就是传入的Promise对象的状况。

Promise.reject()

Promise.reject(reason)要领一样返回一个状况为rejectedPromise对象实例。值得注意的是,参数reason(Promise状况rejected的缘由)不管是什么值,都邑传给返回的Promise对象的catch要领指定的函数作为参数。

var p = Promise.reject('Throw some error! Come on! You bite me.');

p.then((res) => {
  console.log("这是then要领");
}).catch((errMsg) => {
  console.log(errMsg);
});

// Throw some error! Come on! You bite me.

promise对象的运用场景——图片加载

var imgPromise = function (url) {
  return new Promise((resolve, reject) => {
    var img = new Image();
    img.src = url;
    img.onload = resolve;
    img.onerror = reject;
  });
}
imgPromise("http://imgurl")
  .then((res) => {
    console.log("图片加载完成");
  })
  .catch((res) => {
    console.log("图片加载失利");
  }):

参考文章

    原文作者:Juven
    原文地址: https://segmentfault.com/a/1190000009272841
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞