首頁  >  文章  >  web前端  >  詳細了解Nodejs中的Promise對象

詳細了解Nodejs中的Promise對象

青灯夜游
青灯夜游轉載
2021-03-30 18:44:341991瀏覽

本篇文章帶大家了解一下Nodejs中的Promise物件。有一定的參考價值,有需要的朋友可以參考一下,希望對大家有幫助。

詳細了解Nodejs中的Promise對象

相關推薦:《nodejs 教學

Promise物件

1. promise用來做什麼?

我們的需求是一次的去執行非同步程式碼

#我們的做法是在非同步請求成功後的回呼函數裡,執行下一個非同步請求

但是這樣就出現了回調地獄(回呼函數中嵌套了回調函數,程式碼的閱讀性低,維護不變,讓人看著害怕)

promise就是用來解決回呼地獄的

#回呼地獄範例:

// 需求:一次的读取a,b,c这三个文件
const fs = require("fs");

// 读a文件
fs.readFile(`${__dirname}/etc/a.txt`, "utf-8", (err, data) => {
  if (err) {
    console.log(err);
  } else {
    console.log(data);
    // 读b文件
    fs.readFile(`${__dirname}/etc/b.txt`, "utf-8", (err, data) => {
      if (err) {
        console.log(err);
      } else {
        console.log(data);
        // 读c文件
        fs.readFile(`${__dirname}/etc/c.txt`, "utf-8", (err, data) => {
          if (err) {
            console.log(err);
          } else {
            console.log(data);
          }
        });
      }
    });
  }
});

2. promise工作流程

es6的語法,es6.ruanyifeng.com

Promise物件是一個建構函數,用來產生promise實例

Promise建構子接受一個函數作為參數

這個作為參數的函數,又有兩個參數,這兩個參數分別是resolve和reject

這兩個參數它們也是函數,只不過這兩個函數由javascript 引擎提供,不用自己部署

非同步操作成功後呼叫resolve()方法,他內部呼叫了then()裡面的第一個參數函數

非同步操作成功後呼叫reject()方法,他內部呼叫了then()裡面的第二個參數函數.

const fs = require("fs");
// 调用Promise构造函数,创建一个promise的实例
let p = new Promise((resolve, reject) => {
  // 写异步操作(读文件)
  fs.readFile(`${__dirname}/etc/a.txt`, "utf-8", (err, data) => {
    if (!err) {
      // 操作成功(读文件成功)
      resolve(data); // 调用resolve方法
      // 调用then()里面的第一个参数函数
    } else {
      reject(err); // 调用reject方法
      // 调用then()里面的第二个参数函数
    }
  });
});

p.then(
  (data) => {
    console.log(data);
  },
  (err) => {
    console.log(err);
  }
);

#3. promise原理

# #Promise物件代表一個非同步操作.

有三種狀態: pending (進行中)、fulfilled (已成功)和rejected (已失敗)

#Promise物件的狀態改變,只有兩種可能:從pending變成fulfilled和從pending變成rejected。

只有非同步操作的結果,可以決定目前是哪一種狀態,任何其他操作都無法改變這個狀態

如果非同步操作成功了(讀檔成功了),從pending (進行中)變成fulfilled (已成功) ;

如果非同步操作失敗了(讀檔失敗了),從pending (進行中)變成rejected (已失敗) ;

狀態如果已經確定了,就不會再去改變這個狀態了

4. promise特點及其封裝

Promise新建後就會立即執行

所以不要在promise裡面寫其他的程式碼,只寫這個非同步操作的程式碼就可以了

const fs = require("fs");
function getPromise(filename) {
  // 调用Promise构造函数,创建一个promise的实例
  return new Promise((resolve, reject) => {
    // 写异步操作(读文件)
    fs.readFile(`${__dirname}/etc/${filename}.txt`, "utf-8", (err, data) => {
      if (!err) {
        // 操作成功(读文件成功)
        resolve(data); // 调用resolve方法
        // 调用then()里面的第一个参数函数
      } else {
        reject(err); // 调用reject方法
        // 调用then()里面的第二个参数函数
      }
    });
  });
}

// console.log(getPromise("a"));
getPromise("a").then(
  (data) => {
    console.log(data);
  },
  (err) => {
    console.log(err);
  }
);

#5. promise正確寫法

  • promise如何解決回呼地獄
  • -》 鍊式程式設計解決

    **我們用promise解決的問題:讓非同步操作有順序,並且不能有回呼地獄**

  • 讓非同步操作有順序本質是:

    #非同步運算實際上是沒有順序的

在非同步操作成功後的回呼函數裡傳回另外的promise,呼叫他的then方法

const fs = require("fs");
function getPromise(filename) {
  // 调用Promise构造函数,创建一个promise的实例
  return new Promise((resolve, reject) => {
    // 写异步操作(读文件)
    fs.readFile(`${__dirname}/etc/${filename}.txt`, "utf-8", (err, data) => {
      if (!err) {
        // 操作成功(读文件成功)
        resolve(data); // 调用resolve方法
        // 调用then()里面的第一个参数函数
      } else {
        reject(err); // 调用reject方法
        // 调用then()里面的第二个参数函数
      }
    });
  });
}

// console.log(getPromise("a"));
getPromise("a")
  .then((data) => {
    console.log(data);
    //调用函数得到一个读b文件的promise对象并返回
    return getPromise("b");
  })
  .then((data) => {
    console.log(data);
    //调用函数得到一个读c文件的promise对象并返回
    return getPromise("c");
  })
  .then((data) => {
    console.log(data);
  });
#########6. promise的其他方法####### ###############catch()################能夠抓取錯誤的########
const fs = require("fs");
function getPromise(filename) {
  // 调用Promise构造函数,创建一个promise的实例
  return new Promise((resolve, reject) => {
    // 写异步操作(读文件)
    fs.readFile(`${__dirname}/etc/${filename}.txt`, "utf-8", (err, data) => {
      if (!err) {
        // 操作成功(读文件成功)
        resolve(data); // 调用resolve方法
        // 调用then()里面的第一个参数函数
      } else {
        reject(err); // 调用reject方法
        // 调用then()里面的第二个参数函数
      }
    });
  });
}

// console.log(getPromise("a"));
getPromise("a")
  .then((data) => {
    console.log(data);
    //调用函数得到一个读b文件的promise对象并返回
    return getPromise("b");
  })
  .then((data) => {
    console.log(data);
    //调用函数得到一个读c文件的promise对象并返回
    return getPromise("c");
  })
  .then((data) => {
    console.log(data);
  })
  .catch((err) => {
    console.log(err);
  });
## ##########all()######
const fs = require("fs");
function getPromise(filename) {
  // 调用Promise构造函数,创建一个promise的实例
  return new Promise((resolve, reject) => {
    // 写异步操作(读文件)
    fs.readFile(`${__dirname}/etc/${filename}.txt`, "utf-8", (err, data) => {
      if (!err) {
        // 操作成功(读文件成功)
        resolve(data); // 调用resolve方法
        // 调用then()里面的第一个参数函数
      } else {
        reject(err); // 调用reject方法
        // 调用then()里面的第二个参数函数
      }
    });
  });
}

let p1 = getPromise("a");
let p2 = getPromise("b");
let p3 = getPromise("c");

// Promise.all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例
let pAll = Promise.all([p1, p2, p3]);
// 一个都不能少,每一个promise都要读取成功才会成功,相当于是并且
pAll.then((data) => {
  console.log(data);
});
#############race######
const fs = require("fs");
function getPromise(filename) {
  // 调用Promise构造函数,创建一个promise的实例
  return new Promise((resolve, reject) => {
    // 写异步操作(读文件)
    fs.readFile(`${__dirname}/etc/${filename}.txt`, "utf-8", (err, data) => {
      if (!err) {
        // 操作成功(读文件成功)
        resolve(data); // 调用resolve方法
        // 调用then()里面的第一个参数函数
      } else {
        reject(err); // 调用reject方法
        // 调用then()里面的第二个参数函数
      }
    });
  });
}

let p1 = getPromise("a");
let p2 = getPromise("b");
let p3 = getPromise("c");

// Promise.race()方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例
let pRace = Promise.race([p1, p2, p3]);
// 只要有一个promise执行成功,那这个pRace就成功,相当于是或者
pRace.then((data) => {
  console.log(data);
});
########更多程式相關知識,請造訪:###程式設計影片###! ! ###

以上是詳細了解Nodejs中的Promise對象的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:csdn.net。如有侵權,請聯絡admin@php.cn刪除