Réécrivez le titre comme suit : Comment convertir l'API de rappel existante en formulaire de promesse ?
P粉268654873
P粉268654873 2023-08-21 18:34:55
0
2
414
<p>Je souhaite utiliser des promesses pour le gérer, mais le format de mon API de rappel est le suivant : </p> <h3>1. Chargement du DOM ou autres événements ponctuels : </h3> <pre class="brush:php;toolbar:false;">window.onload; // Définir comme fonction de rappel ... window.onload = fonction() { };</pré> <h3>2. Fonction de rappel ordinaire : </h3> <pre class="brush:php;toolbar:false;">requête de fonction (onChangeHandler) { ... } requête(fonction() { // modifié ... });</pré> <h3>3. Fonction de rappel de style nœud ("nodeback") : </h3> <pre class="brush:php;toolbar:false;">function getStuff(dat, callback) { ... } getStuff("dataParam", fonction (erreur, données) { ... })</pré> <h3>4. L'ensemble de la bibliothèque utilise des fonctions de rappel de style nœud : </h3> <pre class="brush:php;toolbar:false;">API; API.one (fonction (erreur, données) { API.two(function(err, data2) { API.trois (fonction (erreur, données3) { ... }); }); });</pré> <h3>Comment utiliser les promesses pour gérer cette API et comment la « promettre » ? </h3>
P粉268654873
P粉268654873

répondre à tous(2)
P粉618358260

Aujourd'hui, je peux le faire Node.js中使用Promisecomme une méthode Javascript normale.

Un exemple Promise simple et basique (en utilisant la méthode KISS) :

NormalCode API asynchrone Javascript :

function divisionAPI (number, divider, successCallback, errorCallback) {

    if (divider == 0) {
        return errorCallback( new Error("Division by zero") )
    }

    successCallback( number / divider )

}

PromiseCode API asynchrone Javascript :

function divisionAPI (number, divider) {

    return new Promise(function (fulfilled, rejected) {

        if (divider == 0) {
            return rejected( new Error("Division by zero") )
        }

        fulfilled( number / divider )

     })

}

(Je recommande de visiter cette excellente source)

De plus, Promise也可以与ES7中的asyncawait一起使用,使程序流程等待fulfilled peut également être utilisé avec asyncawait dans ES7 pour faire en sorte que le flux du programme attende le résultat fulfilled, comme indiqué ci-dessous :

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()方法运行代码

En utilisant le même code, vous pouvez utiliser la méthode .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-nativePeut également être utilisé sur n'importe quelle plate-forme basée sur Node.js, telle que react-native.

Bonus : une méthode de mixing
(Supposons que la méthode de rappel ait deux paramètres, erreur et résultat)

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 )

     })

}

La méthode ci-dessus peut répondre aux résultats des rappels à l'ancienne et de l'utilisation de Promise.

J'espère que cela vous aidera.

P粉680087550

Les promesses ont un état, elles commencent dans un état en attente et peuvent être résolues comme :

  • Implemented signifie que le calcul a été effectué avec succès.
  • Rejeté signifie que le calcul a échoué.

Les fonctions qui renvoient une promesse ne doivent pas lever d'exception mais doivent plutôt renvoyer un rejet. Lancer une exception à partir d'une fonction qui renvoie une promesse vous obligera à utiliser à la fois } catch { } catch { .catch et .catch. Les personnes utilisant des API basées sur des promesses ne veulent pas que les promesses lèvent des exceptions. Si vous n'êtes pas sûr du fonctionnement des API asynchrones dans JS, commencez par consultez cette réponse

.

1. Chargement du DOM ou autres événements ponctuels :

.then Par conséquent, créer des promesses signifie généralement préciser quand elles se résolvent, c'est-à-dire quand elles passent à l'étape Réalisée ou Rejetée pour indiquer que les données sont disponibles (et accessibles via

).

PromiseUtilisez une implémentation de promesse moderne (comme les promesses natives ES6) qui prend en charge

les constructeurs :

function load() {
    return new Promise(function(resolve, reject) {
        window.onload = resolve;
    });
}
Vous pouvez ensuite utiliser la promesse générée comme ceci :

load().then(function() {
    // 在onload之后执行操作
});
Utilisez une bibliothèque qui prend en charge le délai (ici nous utilisons $q comme exemple, mais nous utiliserons également jQuery plus tard) :

function load() {
    var d = $q.defer();
    window.onload = function() { d.resolve(); };
    return d.promise;
}
Ou utilisez une API similaire à jQuery pour vous connecter à un événement qui se produit une seule fois :

function done() {
    var d = $.Deferred();
    $("#myObject").once("click",function() {
        d.resolve();
    });
    return d.promise();
}

2. Rappel ordinaire :

onSuccessonFailCes API sont assez courantes car les rappels sont courants en JS. Regardons les situations courantes

 : 

function getUserData(userId, onLoad, onFail) { …
PromiseUtilisez une implémentation de promesse moderne (comme les promesses natives ES6) qui prend en charge les constructeurs :

function getUserDataAsync(userId) {
    return new Promise(function(resolve, reject) {
        getUserData(userId, resolve, reject);
    });
}
Utilisez une bibliothèque qui prend en charge le délai (ici, nous utilisons jQuery comme exemple, mais nous avons également utilisé $q auparavant) :

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 fournit également des expressions sous la forme , comme indiqué ci-dessous :

function getUserDataAsync(userId) {
    return $.Deferred(function(dfrd) {
        getUserData(userId, dfrd.resolve, dfrd.reject);
    }).promise();
}
resolverejectRemarque : Nous profitons ici du fait que les méthodes différées de jQuery sont « détachables », c'est-à-dire qu'elles sont liées à une instance de jQuery.Deferred() ; Toutes les bibliothèques ne proposent pas cette fonctionnalité.

3. Rappel de style de nœud ("nodeback") :

Les rappels de style nœud (nodebacks) ont un format spécifique où le rappel est toujours le dernier argument et son premier argument est l'erreur. Convertissez-le d'abord manuellement en promesse :

getStuff("dataParam", function(err, data) { …
Convertir en :

function getStuffAsync(param) {
    return new Promise(function(resolve, reject) {
        getStuff(param, function(err, data) {
            if (err !== null) reject(err);
            else resolve(data);
        });
    });
}
En utilisant defer, vous pouvez faire ce qui suit (nous avons utilisé Q comme exemple, bien que Q prenne désormais en charge une nouvelle syntaxe vous devriez préférer cette syntaxe ) :

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;   
}
En général, vous ne devriez pas faire trop de travail manuel pour convertir des éléments en promesses, la plupart des bibliothèques de promesses conçues pour Node ainsi que les promesses natives dans Node 8+ ont des méthodes intégrées pour convertir les nodebacks en promesses. Par exemple 🎜
var getStuffAsync = Promise.promisify(getStuff); // Bluebird
var getStuffAsync = Q.denodeify(getStuff); // Q
var getStuffAsync = util.promisify(getStuff); // 原生承诺,仅限Node

4. L'ensemble de la bibliothèque utilise des rappels de style Node :

Il n'y a pas de règle d'or ici, vous pouvez les transformer en engagements un à un. Cependant, certaines implémentations de promesse vous permettent de le faire par lots, par exemple dans Bluebird, convertir l'API nodeback en API de promesse est aussi simple que ceci :

Promise.promisifyAll(API);

ou utilisez native Promise dans Node :

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}), {});

Remarque :

  • C'est également une bonne pratique de rejeter la promesse lorsque vous lancez une exception dans le .then处理程序中时,当然不需要将事物转换为承诺。从.then处理程序返回一个承诺将使用该承诺的值解决或拒绝。从.thenhandler - c'est ce qu'on appelle la sécurité du lancement de promesses.
  • En réalité onload情况中,您应该使用addEventListener而不是onX.
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal