從入門到放棄之promise用法(上)

參考文獻

1、promise的簡述

含義

  • Promise是異步編程的一種解決方案,比傳統的解決方案——回調函數和事件——更合理和更強大。它由社區最先提出和實現,ES6將其寫進了語言標準,統一了用法,原生提供了Promise對象。
  • 所謂Promise,簡單說就是一個容器,裏面保存着某個將來纔會結束的事件(一般是一個異步操做)的結果。從語法上說,Promise 是一個對象,從它能夠獲取異步操做的消息。Promise 提供統一的 API,各類異步操做均可以用一樣的方法進行處理。

簡單說promise就是一個承諾,將來纔會實現。好比媳婦等我有錢了給你買包, 先等着,給你個承諾,等有錢了再買。承諾就是一個等待態,你能夠設置成功或者失敗,即買包和不買包,這就是下面所說的三個狀態了。es6

特色

  • 對象的狀態不受外界影響。Promise對象表明一個異步操做,有三種狀態:pending(進行中)、resolves(已成功)和rejected(已失敗)。
  • 一旦狀態改變,就不會再變。只有兩種可能:從pending變爲fulfilled和從pending變爲rejected。

簡單說就是Promise對象有三種狀態,一旦成功就不能失敗,一旦失敗就不能成功編程

主要解決回調地獄,函數嵌套的問題

  • 好比看咱們下面的代碼
let fs = require("fs");
fs.readFile("a.txt",'utf8',function(data1){ 
    fs.readFile("b.txt",'utf8',function(data2){ 
        console.log(data1,data2);
    })
})
複製代碼

data2數據須要依賴上一次的返回結果data1時,就會形成嵌套問題,當無限嵌套下去,就會造成回調地獄問題, 下面咱們來看promise基礎用法,怎麼解決這類問題數組

2、promise的基礎用法

建立一個promise實例

  • Promise自己是一個構造函數,須要咱們new 一個實例,傳遞一個函數做爲參數(咱們稱之爲執行器函數 executor),函數接收兩個參數 resolve(成功函數) 、reject(失敗函數)
let p =new Promise((resolve,reject)=>{
    //執行器默認在new時就會被調用,當即執行 
    console.log("1")
    resolve("123") //成功函數resolve,傳遞了123
});
複製代碼

這有什麼用呢,咱們來看p的then方法怎麼獲得123promise

then鏈式寫法

  • then中傳遞兩個函數,第一個函數對應成功時候回調(即resolve('123')),第一個函數對應失敗時候回調(即reject('123'))
  • 這樣的話就把resolve('123')中的123,被then中成功回調所捕獲 data就是123啦,若是傳遞reject('123')就會被失敗回調捕獲
p.then(value=>{ 
    //value指的上面resolve傳遞的參數,成功的緣由
    console.log(value) 
},err=>{
    //失敗的緣由, reject傳遞的參數
     console.log(err)
})
.then(value=>{
    console.log(value)
},err=>{
     console.log(err)
})
複製代碼
  • 回想下咱們如何用promise解決上述嵌套問題
let fs = require('fs');
function read(file){
    return new Promise(function(resolve,reject){
        fs.readFile(file,'utf8',function(err,data){
            if (err) {
                return reject(err);
            }
            resolve(data);
        })
    })
}
read('./a.txt').then(function(data){
    return read('./b.txt');
}).then(function(data){
    console.log(data);
})
複製代碼
  • 上述的寫法是否是更具備流程感
  • then還能夠穿透,什麼意思呢,直接上代碼
let Promise = require('./Promise');
let promise = new Promise((resolve,reject)=>{
  resolve('hello');
});
promise.then().then().then(data=>{ //能夠無限的then,但結果仍會拿到
  console.log(data); //'hello'
},err=>{
  console.log('err',err);
})

複製代碼

錯誤處理catch

  • catch捕獲錯誤,與try/catch語句有相似的功能,能夠把then第二個參數省去,在最後面寫上.catch
p.then().then().catch(err=>{
    console.log(err)
})
複製代碼

Promise.all()

  • Proise.all()在全部的異步操做執行完後才執行的回調,接受一個數組,數組中每項都應是一個promise實例,Promise.all()返回的結果也是一個promise,所以也能夠.then下去,上一段代碼吧
let fs = require("fs");
function read(path) {
  return new Promise((resolve, reject) => {
    fs.readFile(path, 'utf8', function(err, data) {
      if (err) return reject(err);
      resolve(data);
    });
  });
}
Promise.all([read("1.txt"), read("2.txt")]).then( //能夠then說明Promise.all()返回結果也是promise
  data => {
    console.log(data);// [1.txt內容,2.txt內容]
  },
  err => {
    console.log(err);
  }
);
複製代碼

Promise.race()

  • 用法跟Promise.all()很像,指的是誰跑得快,執行誰的回調。
let fs = require("fs");
function read(path) {
  return new Promise((resolve, reject) => {
    fs.readFile(path, 'utf8', function(err, data) {
      if (err) return reject(err);
      resolve(data);
    });
  });
}
Promise.all([read("1.txt"), read("2.txt")]).then( //能夠then說明Promise.all()返回結果也是promise
  data => {
    console.log(data);// [1.txt或者2.txt內容] 
  },
  err => {
    console.log(err);
  }
);
複製代碼

讀到這裏,相信你們看到這裏都應該大概對promise有必定的瞭解,下一章帶領你們手寫一套符合promise A+規範的代碼。bash

相關文章
相關標籤/搜索