Tulis semula tajuk sebagai: Bagaimana untuk menukar API panggil balik sedia ada kepada borang Promise?
P粉268654873
P粉268654873 2023-08-21 18:34:55
0
2
427
<p>Saya mahu menggunakan janji untuk mengendalikannya, tetapi format API panggil balik saya adalah seperti berikut: </p> <h3>1. Pemuatan DOM atau acara sekali lagi: </h3> <pre class="brush:php;toolbar:false;">window.onload; ... window.onload = function() { };</pre> <h3>2. Fungsi panggil balik biasa: </h3> <pre class="brush:php;toolbar:false;">permintaan fungsi(onChangeHandler) { ... } permintaan(fungsi() { // berubah ... });</pre> <h3>3. Fungsi panggil balik gaya nod ("nodeback"): </h3> <pre class="brush:php;toolbar:false;">function getStuff(dat, callback) { ... } getStuff("dataParam", fungsi(err, data) { ... })</pre> <h3>4. Keseluruhan pustaka menggunakan fungsi panggil balik gaya Nod: </h3> <pre class="brush:php;toolbar:false;">API; API.one(function(err, data) { API.two(function(err, data2) { API.tiga(fungsi(err, data3) { ... }); }); });</pre> <h3>Bagaimanakah saya menggunakan janji untuk mengendalikan API ini dan bagaimanakah saya "menjanjikan"nya? </h3>
P粉268654873
P粉268654873

membalas semua(2)
P粉618358260

Hari ini, saya boleh melakukannya Node.js中使用Promisesebagai 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 )

}

PromiseKod 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-nativeJuga 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粉680087550

Janji ada keadaan, ia bermula dalam keadaan tertunda dan boleh diselesaikan sebagai:

  • Dilaksanakan bermaksud pengiraan selesai dengan jayanya.
  • Ditolak bermaksud pengiraan gagal.

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

.

1. Pemuatan DOM atau acara sekali lagi:

.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

).

PromiseGunakan pelaksanaan janji moden (seperti janji ES6 asli) yang menyokong

pembina:

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();
}

2. Panggilan balik biasa:

onSuccessonFailAPI ini agak biasa kerana panggilan balik adalah perkara biasa dalam JS. Mari lihat situasi biasa

:

function getUserData(userId, onLoad, onFail) { …
PromiseGunakan 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();
}
resolverejectNota: 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.

3. Panggilan balik gaya nod ("nodeback"):

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

4 Seluruh perpustakaan menggunakan panggilan balik gaya Nod:

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:

  • Adalah juga amalan yang baik untuk menolak janji apabila anda membuang pengecualian dalam .then处理程序中时,当然不需要将事物转换为承诺。从.then处理程序返回一个承诺将使用该承诺的值解决或拒绝。从.thenpengendali - ini dikenali sebagai keselamatan melontar janji.
  • Sebenarnya onload情况中,您应该使用addEventListener而不是onX.
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan