Rumah > Soal Jawab > teks badan
P粉6183582602023-08-22 16:14:21
Hari ini, saya boleh melakukannya Node.js
中使用Promise
sebagai kaedah Javascript biasa.
Contoh Promise
yang mudah dan asas (menggunakan kaedah KISS):
BiasaKod API tak segerak Javascript:
function divisionAPI (number, divider, successCallback, errorCallback) { if (divider == 0) { return errorCallback( new Error("Division by zero") ) } successCallback( number / divider ) }
Promise
Kod API tak segerak JavaScript:
function divisionAPI (number, divider) { return new Promise(function (fulfilled, rejected) { if (divider == 0) { return rejected( new Error("Division by zero") ) } fulfilled( number / divider ) }) }
(Saya cadangkan melawat sumber hebat ini)
Selain itu, Promise
也可以与ES7
中的asyncawait
一起使用,使程序流程等待fulfilled
juga boleh digunakan dengan asyncawait
dalam ES7
untuk membuat aliran program menunggu keputusan dipenuhi
, seperti yang ditunjukkan di bawah:
function getName () { return new Promise(function (fulfilled, rejected) { var name = "John Doe"; // 在调用fulfilled()方法之前等待3000毫秒 setTimeout ( function() { fulfilled( name ) }, 3000 ) }) } async function foo () { var name = await getName(); // 等待fulfilled结果! console.log(name); // 控制台在3000毫秒后输出"John Doe" } foo() // 调用foo()方法运行代码
Menggunakan kod yang sama, anda boleh menggunakan kaedah .then()
:
function getName () { return new Promise(function (fulfilled, rejected) { var name = "John Doe"; // 在调用fulfilled()方法之前等待3000毫秒 setTimeout ( function() { fulfilled( name ) }, 3000 ) }) } // 控制台在3000毫秒后输出"John Doe" getName().then(function(name){ console.log(name) })
Promise
也可以在任何基于Node.js的平台上使用,比如react-native
Juga boleh digunakan pada mana-mana platform berasaskan Node.js, seperti react-native
.
Bonus: kaedah mencampurkan
(Andaikan kaedah panggil balik mempunyai dua parameter, ralat dan hasil)
function divisionAPI (number, divider, callback) { return new Promise(function (fulfilled, rejected) { if (divider == 0) { let error = new Error("Division by zero") callback && callback( error ) return rejected( error ) } let result = number / divider callback && callback( null, result ) fulfilled( result ) }) }
Kaedah di atas boleh bertindak balas kepada keputusan panggilan balik gaya lama dan penggunaan Promise.
Semoga ini membantu.
P粉6800875502023-08-22 11:07:09
Janji ada keadaan, ia bermula dalam keadaan tertunda dan boleh diselesaikan sebagai:
Fungsi yang mengembalikan janji tidak seharusnya membuang pengecualian tetapi sebaliknya membalas penolakan. Melemparkan pengecualian daripada fungsi yang mengembalikan janji akan memaksa anda menggunakan kedua-dua } catch {
} catch {
和 .catch
dan .catch
. Orang yang menggunakan API berasaskan janji tidak mahu janji membuang pengecualian. Jika anda tidak pasti cara API async berfungsi dalam JS, mula-mula lihat jawapan ini
.then
Oleh itu, mencipta janji biasanya bermaksud menentukan bila ia diselesaikan - bermakna apabila ia beralih ke peringkat Dipenuhi atau Ditolak untuk menunjukkan bahawa data itu tersedia (dan boleh diakses menggunakan
Promise
Gunakan pelaksanaan janji moden (seperti janji ES6 asli) yang menyokong
function load() { return new Promise(function(resolve, reject) { window.onload = resolve; }); }Anda kemudian boleh menggunakan janji yang dijana seperti ini:
load().then(function() { // 在onload之后执行操作 });Gunakan perpustakaan yang menyokong kelewatan (di sini kami menggunakan $q sebagai contoh, tetapi kami juga akan menggunakan jQuery kemudian):
function load() { var d = $q.defer(); window.onload = function() { d.resolve(); }; return d.promise; }Atau gunakan API yang serupa dengan jQuery untuk menyambung ke acara yang berlaku sekali:
function done() { var d = $.Deferred(); $("#myObject").once("click",function() { d.resolve(); }); return d.promise(); }
onSuccess
和onFail
API ini agak biasa kerana panggilan balik adalah perkara biasa dalam JS. Mari lihat situasi biasa
function getUserData(userId, onLoad, onFail) { …
Promise
Gunakan pelaksanaan janji moden (seperti janji ES6 asli) yang menyokong pembina:
function getUserDataAsync(userId) { return new Promise(function(resolve, reject) { getUserData(userId, resolve, reject); }); }Gunakan perpustakaan yang menyokong kelewatan (di sini kami menggunakan jQuery sebagai contoh, tetapi kami juga menggunakan $q sebelum ini):
function getUserDataAsync(userId) { var d = $.Deferred(); getUserData(userId, function(res){ d.resolve(res); }, function(err){ d.reject(err); }); return d.promise(); }
$.Deferred(fn)
形式,它的优点是允许我们编写一个非常接近new Promise(fn)
jQuery juga menyediakan ungkapan dalam bentuk , seperti yang ditunjukkan di bawah:
function getUserDataAsync(userId) { return $.Deferred(function(dfrd) { getUserData(userId, dfrd.resolve, dfrd.reject); }).promise(); }
resolve
和reject
Nota: Di sini kami mengambil kesempatan daripada fakta bahawa kaedah tertunda jQuery adalah "boleh ditanggalkan"; iaitu ia terikat kepada contoh jQuery.Deferred(). Tidak semua perpustakaan menyediakan fungsi ini. Panggil balik gaya nod (nodeback) mempunyai format khusus di mana panggilan balik sentiasa menjadi hujah terakhir dan hujah pertamanya ialah ralat. Mula-mula tukarkannya kepada janji secara manual:
getStuff("dataParam", function(err, data) { …Tukar kepada:
function getStuffAsync(param) { return new Promise(function(resolve, reject) { getStuff(param, function(err, data) { if (err !== null) reject(err); else resolve(data); }); }); }Menggunakan penangguhan, anda boleh melakukan perkara berikut (kami menggunakan Q sebagai contoh, walaupun Q kini menyokong sintaks baharu anda harus memilih sintaks itu ):
function getStuffAsync(param) { var d = Q.defer(); getStuff(param, function(err, data) { if (err !== null) d.reject(err); else d.resolve(data); }); return d.promise; }Secara amnya, anda tidak sepatutnya melakukan terlalu banyak kerja manual dalam menukar sesuatu kepada janji, kebanyakan perpustakaan janji yang direka untuk Node serta janji asli dalam Node 8+ mempunyai kaedah terbina dalam untuk menukar nodeback kepada janji. Contohnya 🎜
var getStuffAsync = Promise.promisify(getStuff); // Bluebird var getStuffAsync = Q.denodeify(getStuff); // Q var getStuffAsync = util.promisify(getStuff); // 原生承诺,仅限Node
Tiada peraturan emas di sini, anda boleh menukarnya menjadi komitmen satu demi satu. Walau bagaimanapun, beberapa pelaksanaan janji membolehkan anda melakukan ini dalam kelompok, contohnya dalam Bluebird menukar API nodeback kepada API janji adalah semudah ini:
Promise.promisifyAll(API);
atau gunakan Janji asli dalam Nod:
const { promisify } = require('util'); const promiseAPI = Object.entries(API).map(([key, v]) => ({key, fn: promisify(v)})) .reduce((o, p) => Object.assign(o, {[p.key]: p.fn}), {});
Nota:
.then
处理程序中时,当然不需要将事物转换为承诺。从.then
处理程序返回一个承诺将使用该承诺的值解决或拒绝。从.then
pengendali - ini dikenali sebagai keselamatan melontar janji. onload
情况中,您应该使用addEventListener
而不是onX
.