Javascript的特點是異步,Javascript不能等待,如果你實現某件需要等待的事情,你不能停在那裡一直等待結果回來,相反,底線是使用回調callback:你定義一個函數,這個函數只有等到結果可用時才能被呼叫。
這種回調模型對於好的程式碼組織是沒有問題的,但是也可以透過從原始回呼切換到promise解決很多問題,將promise看成是一個標準的資料容器,這樣會簡化你的程式碼組織,可以成為基於promise的架構。
什麼是Promise?
一個promise是一個帶有".then()"方法的對象,其代表的是一個操作的結果可能還沒有或不知道,無論誰訪問這個對象,都能夠使用".then()"方法加入回呼等待操作出現成功結果或失敗時的提醒通知,。
那為什麼這樣做好處會優於回調呢?標準的回呼模式在我們處理請求時需要同時提供回呼函數:
request(url, function(error, response) { // handle success or error. }); doSomethingElse();
很不幸,這段程式碼意味著這個request函數並不知道它自己什麼時候能夠完成,當然也沒有必要,我們最終透過回調傳遞結果。這會導致多個回調形成了嵌套回調,或稱為回調陷阱。
queryTheDatabase(query, function(error, result) { request(url, function(error, response) { doSomethingElse(response, function(error, result) { doAnotherThing(result, function(error, result) { request(anotherUrl, function(error, response) { ... }); }); }); }); });
Promise能夠解決這個問題,允許低層程式碼建立一個request然後返回一個對象,其代表著未完成的操作,讓呼叫者去決定應該加入什麼回呼。
Promise是什麼?
promise是一個非同步程式設計的抽象,它是一個傳回值或拋出exception的代理對象,一般promise物件都有一個then方法,這個then方法是我們如何獲得傳回值(成功實現承諾的結果值,稱為fulfillment)或拋出exception(拒絕承諾的理由,稱為rejection),then是用兩個可選的回調作為參數,我們可以稱為onFulfilled和OnRejected:
var promise = doSomethingAync()
promise.then(onFulfilled, onRejected)
當這個promise被解決了,也就是非同步過程完成後,onFulfilled和OnRejected中任何一個將被調用,
因此,一個promise有以下三個不同狀態:
■pending待承諾 - promise初始狀態
■fulfilled實現承諾 - 一個承諾成功實現狀態
■rejected拒絕承諾 - 一個承諾失敗的狀態
以讀取檔案為案例,以下是使用回呼實作讀取檔案後應該做什麼事情(輸出列印):
readFile(function (err, data) { if (err) return console.error(err) console.log(data) })
如果我們的readFile函數回傳一個promise,那麼我們可以如下實作同樣的邏輯(輸出列印):
var promise = readFile()
promise.then(console.log, console.error)
這裡我們有了一個值promise代表的是非同步操作,我們能夠一直傳遞這個值promise,任何人訪問這個值都能夠使用then來消費使用它,無論這個值代表的非同步操作是否完成或沒有完成,我們也能保證異步的結果不會改變,因為這個promise代表的非同步操作只會執行一次,狀態是要么fulfilled要么是rejected。
理解Promise
Promise可能是不同於日常直覺,為了理解它,一些重要原理必須記牢: .then()總是返回一個新的promise.,如下面代碼:
var promise = readFile()
var promise2 = promise.then(readAnotherFile, console.error)
這裡then的參數readAnotherFile, console.error是代表非同步操作成功後的動作onFulfilled或失敗後的動作OnRejected,也就是說,讀取檔案成功後執行readAnotherFile函數,否則失敗列印記錄錯誤。這種實現是兩個只有一種可能。
我們再看下面上述程式碼如下:
var promise = readFile() var promise2 = promise.then(function (data) { return readAnotherFile() // 如果readFile成功,执行readAnotherFile }, function (err) { console.error(err) // 如果readFile不成功,记录,但是还是执行readAnotherFile return readAnotherFile() }) promise2.then(console.log, console.error) // readAnotherFile函数的执行结果
因為then回傳一個promise,它意味著promise能夠被chain串列鏈條花,這樣能避免回呼地獄:
readFile() .then(readAnotherFile) .then(doSomethingElse) .then(...)
Promise法则有两部分必须分离:
(1).then()总是返回一个新的promise,每次你调用它,它不管回调做什么,因为.then()在回调被调用之前已经给了你一个承诺promise,回调的行为只影响承诺promise的实施,如果回调返回一个值,那么promise将使用那个值,如果这个值是一个promise,返回这个promise实施后的值给这个值,如果回调抛出错误,promise将拒绝错误。
(2)被.then()返回的promise是一个新的promise,它不同于那些.then()被调用的promise,promise长长的链条有时会好些隐藏这个事实,不管如何,每次.then()调用都会产生一个新的promise,这里必须注意的是你真正需要考虑的是你最后调用.then()可能代表失败,那么如果你不捕获这种失败,那么容易导致你的错误exception消失。
一些人认为.then()串联链条调用很类似fluent风格,但是长长的promise链条会让人迷惑,最后切分为一个个有意义的函数:
function getTasks() { return $http.get('http://example.com/api/v1/tasks') .then(function(response) { return response.data; }); } function getMyTasks() { return getTasks() .then(function(tasks) { return filterTasks(tasks, { owner: user.username }); }); }
在这个例子中,两个函数各自获得一个promise,携带了一个回调函数。
有趣的Promise
同样的promise能够接受任何数目的回调,当一个Promise被解决实施后,其中所有回调函数都会被调用,此外,一个promise在被解决实施后,甚至可以接受一个新的回调,这些回调完成能以正常方式被调用,这就允许我们使用回调实现简单形式的缓存:
var tasksPromise; function getTasks() { taskPromise = taskPromise || getTasksFromTheServer(); return taskPromise; }
这个案例中,getTasks()函数可以被任意次数调用,它总是返回铜牙的promise,其中函数getTasksFromTheServer()却只是被调用一次。
以上这篇NodeJS的Promise的用法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

node、nvm与npm的区别:1、nodejs是项目开发时所需要的代码库,nvm是nodejs版本管理工具,npm是nodejs包管理工具;2、nodejs能够使得javascript能够脱离浏览器运行,nvm能够管理nodejs和npm的版本,npm能够管理nodejs的第三方插件。

Vercel是什么?本篇文章带大家了解一下Vercel,并介绍一下在Vercel中部署 Node 服务的方法,希望对大家有所帮助!

node怎么爬取数据?下面本篇文章给大家分享一个node爬虫实例,聊聊利用node抓取小说章节的方法,希望对大家有所帮助!

node导出模块的两种方式:1、利用exports,该方法可以通过添加属性的方式导出,并且可以导出多个成员;2、利用“module.exports”,该方法可以直接通过为“module.exports”赋值的方式导出模块,只能导出单个成员。

安装node时会自动安装npm;npm是nodejs平台默认的包管理工具,新版本的nodejs已经集成了npm,所以npm会随同nodejs一起安装,安装完成后可以利用“npm -v”命令查看是否安装成功。

node中没有包含dom和bom;bom是指浏览器对象模型,bom是指文档对象模型,而node中采用ecmascript进行编码,并且没有浏览器也没有文档,是JavaScript运行在后端的环境平台,因此node中没有包含dom和bom。

本篇文章带大家聊聊Node.js中的path模块,介绍一下path的常见使用场景、执行机制,以及常用工具函数,希望对大家有所帮助!


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),