Comment lancer jQuery $.ajax appelle à des promesses Bluebird sans le différé anit-pattern

en ce moment j'utilise la promesse.différé dans un fichier central. Cela me permet de résoudre des promesses à un endroit central. J'ai lu que j'utilisais peut-être un modèle anti-et je veux comprendre pourquoi c'est mauvais.

donc dans mon core.js le fichier que j'ai des fonctions comme ceci:

var getMyLocation = function(location) {    
    var promiseResolver = Promise.defer();

    $.get('some/rest/api/' + location)
        .then(function(reponse) {
            promiseResolver.resolve(response);
        )}
        .catch(function(error) {
            promiseResolver.reject(error);
        });

     return promiseResolver.promise;
}

puis dans mon getLocation.js le fichier j'ai le code suivant:

var core = require('core');
var location = core.getMyLocation('Petersburg')
    .then(function(response) {
        // do something with data
    }).catch(throw error);

après avoir lu les documents de Bluebird et de nombreux billets de blog sur les ajournés anti-modèle, je me demande si ce modèle est pratique. J'ai la possibilité de changer cela à la suivante:

core.js

var getMyLocation = function(location) {
    var jqXHR = $.get('some/rest/api/' + location);
    return Promise.resolve(jqXHR)
        .catch(TimeoutError, CancellationError, function(e) {
            jqXHR.abort();
            // Don't swallow it
            throw e;
        });

getLocation.js

var location = core.getMyLocation('Petersburg')
    .then(function(response) {
        // do something
    })
    .catch(function(error) {
        throw new Error();
    });

je suppose que je suis confus par ce qui est la meilleure façon d'avoir une bibliothèque centrale qui traite les requêtes xhr en utilisant jquery pour les appels, mais Bluebird pour les promesses.

19
demandé sur Jeff 2014-06-19 23:54:22

2 réponses

Vous pouvez appeler Promise.resolve sur un jQuery thenable et ont Bluebird assimiler:

var res = Promise.resolve($.get(...)); // res is a bluebird Promise

vous pouvez également retourner les promesses de jQuery directement à l'intérieur d'une chaîne de merles bleus et les faire assimiler.

myBluebirdApi().then(function(){
    return $.get(...);
}).then(function(result){
    // The jQuery thenable was assimilated
});

votre code ci-dessous est proche, mais vous n'avez pas besoin d'attraper TimeoutError puisque jQuery ajax ne les lancera pas. Comme pour attraper l'erreur d'annulation. C'est la meilleure pratique de toute façon pour ce que vous faites si vous vous attendez à devoir annuler la demande.

19
répondu Benjamin Gruenbaum 2015-08-24 16:36:25

pour convertir un thenable en une promesse Bluebird, vous pouvez utiliser can call Promise.resolve comme ceci:

var promise = Promise.resolve($.getJSON(...));

section Bonus:

la plupart des fonctions AJAX de JQuery sont thenable, mais pour votre information, Si vous voulez convertir une fonction qui attend un rappel à une promesse, vous pouvez utiliser Promise.fromNode. Le callback sera appelé avec les arguments err, result comme c'est la convention dans le noeud.js monde:

var promise = Promise.fromNode(function (callback) { request(url, callback); });

si le rappel ne s'attendre à une erreur potentielle pour son premier argument, vous pouvez travailler autour de cela:

var promise = Promise.fromNode(function (callback) {
  FB.api(url, function(response) { callback(response ? response.error : "no response", response); });
});
3
répondu Flimm 2016-08-04 23:35:25