关于Promise

掘金上瞥见一篇写promise的文章,觉得作者写的很棒,文章链接在这:八段代码完全控制 Promise 。看完以后觉得学到了许多,所以又从新把JavaScript Promise迷你书(中文版)刷了一遍,以下是我关于promise的明白。

Promise 是什么?

所谓Promise,简朴说就是一个容器,内里保存着某个将来才会完毕的事宜(通常是一个异步操纵)的效果。从语法上说,Promise 是一个对象,从它能够猎取异步操纵的音讯。Promise 供应一致的 API,种种异步操纵都能够用一样的要领举行处置惩罚。 —— ECMAScript 6 入门 阮一峰

Promise对象代表一个异步操纵,有三种状况:Pending(预备状况),Fulfilled(胜利状况,也称为Resolved状况),Rejected(失利状况)。只要异步操纵的效果能够决议promise对象的状况,操纵胜利后,promise对象由Pending状况转换为Fulfilled状况,此时回调函数会实行 onFulfilled要领。反之,操纵失利,promise对象由pending状况转换为Rejected状况,此时回调函数会实行onRejected要领。
以下图所示:

《关于Promise》

建立一个Promise对象
var p1 = new Promise(function(resolve,reject){
    resolve('resolve');
});
var p2 = new Promise(function(resolve,reject){
    reject('reject');
});

p1 返回一个resolved状况,值为resolve的Promise对象

Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: "resolve"} 

p2 返回一个rejected状况,值为reject的Promise对象

Promise {[[PromiseStatus]]: "rejected", [[PromiseValue]]: "reject"}

Promise 的基础API

1.Promise#then

Promise.then(onFulfilled,onRejected)

then要领定义了promise状况变成resolved或许rejected状况以后的回调函数:

  • pending->resolved:实行onFulfilled函数,而且将promise对象的值传给onFulfilled函数
  • pending->rejected:实行onRejected函数,而且将promise对象的值传给onRejected函数

代码示例以下:

var p = new Promise(function(resolve, reject){
  console.log("create a promise");
  resolve("success");
});

console.log("after new Promise");

p.then(function onFulfilled(value){
  console.log(value);
},function onRejected(error){
  console.log(error);
});

运转效果以下:

"create a promise"
"after new Promise"
"success"

new Promise返回一个resolved状况的promise对象,所以在p.then()要领中挪用的是onFulfilled函数。
建立promise时,promise对象中的函数是马上实行的,并非在挪用then要领的时刻才会去实行,所以首先会输出”create a promise”。然则实行的代码是异步代码,所以”after new Promise”会在”success”之前输出。

2.Promise#catch

promise.catch(onRejected);

catch要领捕捉了promise运转过程当中的非常。catch与then要领中的onRejected的差异是,onRejected 函数只能在promise状况变成rejected的时刻挪用,但catch既能够在promise状况变成rejected的时刻挪用,又能够捕捉第一个onFulfilled要领中涌现的毛病。
能够参考promise迷你书中的这一段代码:

function throwError(value) {
    // 抛出非常
    throw new Error(value);
}
// <1> onRejected不会被挪用
function badMain(onRejected) {
    return Promise.resolve(42).then(throwError, onRejected);
}
// <2> 有非常发作时onRejected会被挪用
function goodMain(onRejected) {
    return Promise.resolve(42).then(throwError).catch(onRejected);
}
// 运转示例
badMain(function(){
    console.log("BAD");
});
goodMain(function(){
    console.log("GOOD");
});

在这段代码中,badMain函数中传入onRejected参数,由于Promise.resolve(42)返回一个resolved状况的promise对象(这个api的用法会在下一节中说到),所以会去挪用throwError函数,throwError函数中抛出的非常onRejected是捕捉不到的,然则catch能够捕捉到。

《关于Promise》

3.Promise.resolve

这个要领会根据传进来的参数的差异,返回差异的promise对象。

//1.传入的参数是一个一般值
var p1 = Promise.resolve(1);//返回一个将该对象作为值的新promise对象
//2.传入的参数是一个Promise对象
var p2 = Promise.resolve(p1);//返回吸收到的promise对象

p1 === p2   //true

在迷你书中引见了三种状况,除了上面两种以外,另有一种thenable范例的对象的时刻,那种这里就不做引见了,有兴致的朋侪能够本身去看看啊~

4.Promise.reject

这个要领跟Promise.resolve要领一样,会根据传进来的参数的差异,返回差异的promise对象。

//1.传入的参数是一个一般值
var p3 = Promise.reject(1);//返回一个将该对象作为值的新promise对象
//2.传入的参数是一个Promise对象
var p4 = Promise.reject(p3);//返回一个新的promise对象

p3 === p4   //false

跟resolve差异的是,当传入的参数是一个Promise对象的时刻,会返回一个rejected状况的新promise对象。

5.Promise.all

Promise.all吸收一个 promise对象的数组作为参数,当这个数组里的一切promise对象悉数变成resolve或reject状况的时刻,它才会去挪用 .then 要领。
示例代码:

var p1 = Promise.resolve(1),
    p2 = Promise.resolve(2),
    p3 = Promise.resolve(3);
Promise.all([p1, p2, p3]).then(function (results) {
    console.log(results);  // [1, 2, 3]
});
6.Promise.race

Promise.race也是吸收一个 promise对象的数组作为参数,参数 promise 数组中的任何一个promise对象假如变成resolve或许reject的话, 该函数就会返回,并运用这个promise对象的值举行resolve或许reject。

var p1 = Promise.resolve(1),
    p2 = Promise.resolve(2),
    p3 = Promise.resolve(3);
Promise.race([p1, p2, p3]).then(function (value) {
    console.log(value);  // 1
});

这里须要注重的是,虽然在p1resolved以后便实行了then要领,然则并非意味着今后的promise对象不实行了,其他的照样promise对象照样要实行的,只是不会再挪用then函数。
下面这个demo便能够看出:

var p1 = new Promise(function(resolve,reject){
  console.log('I am p1!');
  resolve(1);
});
var p2 = new Promise(function(resolve,reject){
  console.log('I am p2!');
  resolve(2);
});
var p3 = new Promise(function(resolve,reject){
  console.log('I am p3!');
  resolve(3);
});
Promise.race([p1, p2, p3]).then(function (value) {
    console.log(value); 
});

运转效果:

I am p1!
I am p2!
I am p3!
1

Promise Demo

这是个很大的demo,,^-^, 涵盖了许多小知识点,

var p_1 = new Promise(function(resolve,reject){
  resolve(1);
});
var p_2 = Promise.resolve(1);
var p_3 = Promise.reject(1);
var p_4 = Promise.resolve(p_2);

// 体式格局1
var p1 = new Promise(function(resolve, reject){
  resolve(Promise.resolve('resolve'));
});

var p2 = new Promise(function(resolve, reject){
  resolve(Promise.reject('reject'));
});

var p3 = new Promise(function(resolve, reject){
  reject(Promise.resolve('resolve'));
});

var p4 = new Promise(function(resolve, reject){
  reject(Promise.reject('reject'));
});
//体式格局2
var p1 = Promise.resolve(Promise.resolve('resolve'))
var p2 = Promise.resolve(Promise.reject('reject'))
var p3 = Promise.reject(Promise.resolve('resolve'))
var p4 = Promise.reject(Promise.reject('reject'))

//定义回调函数
p1.then(
  function fulfilled(value){
    console.log('fulfilled1: ' + value);
  }, 
  function rejected(err){
    console.log('rejected1: ' + err);
  }
);

p2.then(
  function fulfilled(value){
    console.log('fulfilled2: ' + value);
  }, 
  function rejected(err){
    console.log('rejected2: ' + err);
  }
);

p3.then(
  function fulfilled(value){
    console.log('fulfilled3: ' + value);
  }, 
  function rejected(err){
    console.log('rejected3: ' + err);
  }
);

p4.then(
  function fulfilled(value){
    console.log('fulfilled4: ' + value);
  }, 
  function rejected(err){
    console.log('rejected4: ' + err);
  }
);

《关于Promise》

采纳new Promise 体式格局建立对象和采纳Promise.resolve要领建立出来的对象实际上是一样的,能够把Promise.resolve看作new Promise 的语法糖。只不过须要注重的是,在上面引见resolve要领的时刻说过,假如传入的参数是一个promise对象,会直接返回这个对象,,所以p_2===p_4输出的是true,然则经由过程new的体式格局建立出来的对象都是新建立的,所以new出来的对象跟别的对象都不会全等,即p_1===p_2会输出false。

《关于Promise》

两种体式格局定义的p1,p2,p3,p4都是雷同的,从这段代码能够看出,不论是用那种体式格局建立promise对象,假如运用Promise.resolve要领传入一个新对象,照样会去‘读取’(可明白为)这个对象的,然则Promise.reject要领传入一个新对象,并不会去‘读取’这个对象,而会直接返回这个这个对象。(这个‘读取’的观点并非promise中的观点,只是我的个人明白,在八段代码完全控制 Promise 这篇文章中,作者把他解释为‘拆箱’,也是作者的一种让人明白起来更简朴的思绪,至于promise官方文档中的划定,现在还没有去细致深入研讨,有时间会去看一下^-^)

《关于Promise》

《关于Promise》

从这段代码能够看出,两种体式格局的实行递次会有差异,至于为何,本日也查找了许多材料,然则并没有找到缘由,有研讨过的大神迎接指点~~

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