web-dev-qa-db-fra.com

Définir la promesse vide Bluebird comme dans Q

Avec Q, je peux définir une nouvelle promesse avec:

var queue = q();

Mais avec Bluebird si je le fais:

var queue = new Promise();

Je reçois:

TypeError: the promise constructor requires a resolver function

Comment puis-je obtenir le même résultat que j'ai eu avec Q?

Ceci est un extrait de mon code:

var queue    = q()
    promises = [];
queue = queue.then(function () {
    return Main.gitControl.gitAdd(fileObj.filename, updateIndex);
});
// Here more promises are added to queue in the same way used above...
promises.Push(queue);
return Promise.all(promises).then(function () {
   // ...
});
36
Fez Vrasta
var resolver = Promise.defer();
setTimeout(function() {
    resolver.resolve(something); // Resolve the value
}, 5000);
return resolver.promise;

Cette ligne est assez souvent utilisée dans documentation .

Sachez qu'il s'agit généralement d'un anti-modèle pour l'utiliser. Mais si vous savez ce que vous faites, Promise.defer() est un moyen d'obtenir le résolveur similaire à celui de Q.

Il est toutefois déconseillé d'utiliser cette méthode. Bluebird l'a même déconseillé.

Au lieu de cela, vous devriez utiliser cette façon:

return new Promise(function(resolve, reject) {
    // Your code
});

Reportez-vous à la documentation correspondante: Promise.defer () et new Promise () .


Après la mise à jour de votre question, voici votre problème: vous réutilisez la même promesse pour résoudre plusieurs valeurs. Une promesse ne peut être résolue qu'une fois. Cela signifie que vous devez utiliser Promise.defer() autant de fois que vous avez des promesses.

Cela dit, après avoir vu plus de votre code, il semble que vous utilisiez vraiment des anti-modèles. L'un des avantages de l'utilisation des promesses est la gestion des erreurs. Pour votre cas, il vous suffirait du code suivant:

var gitControl = Promise.promisifyAll(Main.gitControl);
var promises = [];
promises.Push(gitControl.gitAddAsync(fileObj.filename, updateIndex));
return promises;

Cela devrait suffire à gérer votre cas d'utilisation. C'est beaucoup plus clair, et cela présente également l'avantage de vraiment gérer correctement les erreurs.

23
Florian Margaine

Florian a donné une bonne réponse Pour répondre à votre question initiale, il existe plusieurs façons de démarrer une chaîne avec Bluebird.

Un des plus simples appelle Promise.resolve() sur rien:

var queue = Promise.resolve(); //resolve a promise with nothing or cast a value

ou

Promise.try(function(...){
    return ...//chain here
});

Alors tu peux faire:

var queue    = Promise.resolve()
    promises = [];
queue = queue.then(function () {
    return Main.gitControl.gitAdd(fileObj.filename, updateIndex);
});

// Here more promises are added to queue in the same way used above...
promises.Push(queue);
return Promise.all(promises).then(function () {
   // ...
});

Personnellement, je ferais quelque chose comme:

//arr is your array of fileObj and updateIndex

Promise.map(arr,function(f){ return Main.gitControl.gitAdd(f.filename,f.updateIndex).
    then (function(result){
        //results here
    });
37
Benjamin Gruenbaum

Je suis tombé sur cette erreur car j'avais une méthode qui récupérait une ressource sur Internet et en renvoyait le contenu, mais je souhaite qu'elle gère les délais de connexion et les tentatives répétées jusqu'à X fois avec des délais entre les deux.

Comme Bluebird.defer est obsolète, j'ai utilisé ceci pour faire cette astuce:

const Promise = require('bluebird');

var fetch = function (options, promise) {
    var resolve, reject;
    if (promise) {
        resolve = promise.resolve;
        reject = promise.reject;
        promise = promise.promise;
    } else {
        promise = new Promise(function () {
            resolve = arguments[0];
            reject = arguments[1];
        });
    }
    var retry = {promise: promise, resolve: resolve, reject: reject};

    // Your logic here that you want to retry
    if (typeof options.x === 'undefined') {
        reject(new Error('X not defined'));
    } else if (options.x < 3) {
        options.x++;
        options.retryAttempt = (options.retryAttempt || 0) + 1;
        console.log(`Retrying in 1 second attempt ${options.retryAttempt}...`);
        setTimeout(() => {
            fetch(options, retry)
        }, 1000);
    } else {
        resolve(options.x);
    }

    return promise;
}

fetch({x:0})
    .then(res => {
        console.log(res);
    })
    .catch(err => {
        throw err;
    });
0
Kus

Je trouve un modèle comme celui-ci utile pour tout type de test d'intégration.

const responseResolver;

const response = new Promise(resolve => {
    responseResolver = resolve;
}).then(data => {
    console.log("data: ", data);
    return data;
});

// mock some method that returns a promise (e.g. waits for a response)
service.getIceCreams = () => response;

// do some assertions while the response is pending

responseResolver("cookie dough"); // will trigger .then: "data: cookie dough"

// do some assertions now that the response is completed
0
Sam Berry