Promise快餐

Promise 是异步编程的一种处理方案,其他的异步编程处理方案另有——回调函数事宜监听宣布定阅,以及ES6新增的Generator

http://www.ruanyifeng.com/blo…
http://es6.ruanyifeng.com/#do…

Promise的状况

  1. Pending(举行中)

  2. Resolved (已完成)

  3. Rejected (已失利)

Promise的特性

  1. 对象的状况不受外界影响。

  2. 一旦状况转变,就不会再变,任何时刻都能够取得这个结果。

Promise的用法

var promise = new Promise(function(resolve, reject) {
  // ... some code

  if (/* 异步操纵胜利 */){
    resolve(value);
  } else {
    reject(error);
  }
});

注重:

resovle和reject函数都是由js引擎供应的函数不必本身定义。

个中 resovle函数的作用是将Promise对象从举行中状况转换为已完成reject函数将Promise对象从举行中状况转换为已失利状况。

Promise.prototype.then()

Promise 实例具有then要领,then要领是定义在原型对象Promise.prototype上的,它的作用是为 Promise 实例增加状况转变时的回调函数。

连续上面的代码:

promise.then(function(res) {
    console.log(res)
}, function(err) {
    console.log(err)
})

then对象吸收两个回调函数作为参数,第一个回调函数是resovle的回调,第二个回调函数是reject的回调。即,一个用于处置惩罚状况为已完成的逻辑,另一个用于处置惩罚已失利的逻辑。

一个Ajax要求的例子:

var getJSON = function(url) {
  var promise = new Promise(function(resolve, reject){
    var client = new XMLHttpRequest();
    client.open("GET", url);
    client.onreadystatechange = handler;
    client.responseType = "json";
    client.setRequestHeader("Accept", "application/json");
    client.send();

    function handler() {
      if (this.readyState !== 4) {
        return;
      }
      if (this.status === 200) {
        resolve(this.response);
      } else {
        reject(new Error(this.statusText));
      }
    };
  });

  return promise;
};

getJSON("/posts.json").then(function(json) {
  console.log('Contents: ' + json);
}, function(error) {
  console.error('出错了', error);
});

Promise.prototype.catch()

Promise.prototype.catch要领是.then(null, rejection)的别号,用于指定发作毛病时的回调函数。不是指then要领的别号而是指resovle的回调函数为null的then要领的别号。

一般引荐运用catch要领来捕捉非常,而不是运用reject的回调函数。

// 不引荐的写法
promise
  .then(function(data) {
    // success
  }, function(err) {
    // error
  });

// 引荐的写法
promise
  .then(function(data) {
    // success
  })
  .catch(function(err) {
    // error
  });

运用catch要领来吸收毛病信息的优点是,Promise 对象的毛病具有“冒泡”性子,会一向向后通报,直到被捕捉为止。所以一个catch能够捕捉链式挪用中多个Promise对象抛出的非常。

链式挪用

当有几个异步操纵须要链式挪用时,promise是支撑的。

一个简朴的链式挪用的例子:

getJSON("/post/1.json").then(function(post) {
  return getJSON(post.commentURL);
}).then(function funcA(comments) {
  console.log("Resolved: ", comments);
}, function funcB(err){
  console.log("Rejected: ", err);
});

Promise的then函数,返回的是一个新的Promise对象。假如返回的对象不是Promise对象会是什么结果呢?
以下是一些考试代码:

var promise = new Promise(function(resolve, reject) {
  let a = '111';
    resolve(a);
});

promise.then(function(res) {
    return null;
}).then(function(res){
    console.log(res);
}).catch(function(err) {
    console.log(err);
})
// null

var b = function() {
    console.log('bb');
}

var promise = new Promise(function(resolve, reject) {
  let a = '111';
    resolve(a);
});

promise.then(function(res) {
    return b();
}).then(function(res){
    console.log(res);
})
// bb
// undefined

能够看出,假如then retrun的不是一个Promise函数时,并不会报错,也没有抛出非常,相当于一个没有实行reject和resovle的Promise对象(个人明白,有失偏颇。望自郑重,择善从之。)。

Promise.all()

在某些时刻,我们须要实行多个异步操纵。这些异步操纵可能有以下几种关联:

  1. 互不关联

  2. 逐一依靠

  3. 部份依靠

  4. 结果依靠(指须要取得所以返回的结果举行下一步的操纵)

Promise.all要领用于将多个 Promise 实例,包装成一个新的 Promise 实例。能够用来处理上面的4关联。
互不关联最好离开挪用,部份依靠、逐一依靠用链式挪用。

Promise.all吸收一个Promise数组作为参数,即数组中的值都是Promise对象,假如不是就会先挪用Promise.resovle要领,将参数转为Promise实例。

// 天生一个Promise对象的数组
var promises = [2, 3, 5, 7, 11, 13].map(function (id) {
  return getJSON('/post/' + id + ".json");
});

Promise.all(promises).then(function (posts) {
  // ...
}).catch(function(reason){
  // ...
});

只有当一切的Promise对象都返回resovle时才会实行then要领,只需有一个Pormise对象返回的是reject,就实行catch。

ps: 另有Promise.race()要领,此要领和Promise.all()差别之处时,只需传入的Promise数组中有一个实例领先转变状况,p的状况就随着转变。谁人领先转变的 Promise 实例的返回值,就通报给p的回调函数。可用于限定要求的最大反应时间。

const p = Promise.race([
  fetch('/resource-that-may-take-a-while'),
  new Promise(function (resolve, reject) {
    setTimeout(() => reject(new Error('request timeout')), 5000)
  })
]);
p.then(response => console.log(response));
p.catch(error => console.log(error));
// 假如凌驾5秒就返回要求超时

Promise.resolve()和Promise.reject()

这两个要领返回一个新的Promise实例,resovle要领返回的实例状况为resolve,同理reject要领返回reject。
都吸收一个参数作为现有的对象,此参数能够为任何值包含null,undefined。
依据吸收的参数,两种要领都邑做出差别的处置惩罚。在此不做细致的引见了,有兴致的能够去看看

http://es6.ruanyifeng.com/#do…

Promise.resolve('foo')
// 等价于
new Promise(resolve => resolve('foo'))

finally()

此要领用于末了实行,不Promise的状况怎样,都邑实行的操纵(另有这类操纵?)。在node中可用于封闭服务器或许数据库衔接。在浏览器中可用于须要在异步函数返回以后实行的操纵。

var p = new Promise(function(resovle.reject){
    resovle('is resovle');
});

p.then(function(res) {
    console.log(res) 
}).finally(function() {
    console.log('is finally');
})
    原文作者:ermu
    原文地址: https://segmentfault.com/a/1190000009930472
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞