web-dev-qa-db-de.com

Definiere ein leeres Bluebird-Versprechen wie in Q

Mit Q kann ich ein neues Versprechen definieren mit:

var queue = q();

Aber mit Bluebird, wenn ich das tue:

var queue = new Promise();

Ich bekomme:

TypeError: the promise constructor requires a resolver function

Wie kann ich dasselbe Ergebnis erzielen, das ich mit Q hatte?

Dies ist ein Ausschnitt meines Codes:

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;

Diese Zeile wird häufig in der Dokumentation verwendet.

Beachten Sie, dass dies normalerweise ein Anti-Pattern ist, um dies zu verwenden. Aber wenn Sie wissen, was Sie tun, ist Promise.defer() eine Möglichkeit, den Resolver auf die gleiche Weise wie Q zu erhalten.

Es wird jedoch davon abgeraten, diese Methode zu verwenden. Bluebird hat es sogar abgelehnt.

Verwenden Sie stattdessen diesen Weg:

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

Siehe die entsprechenden Dokumentationsbits: Promise.defer () und new Promise () .


Nach dem Update Ihrer Frage, hier ist Ihr Problem: Sie verwenden dasselbe Versprechen, um mehrere Werte aufzulösen. Ein Versprechen kann nur einmal gelöst werden. Es bedeutet, dass Sie Promise.defer() so oft verwenden müssen, wie Sie es versprochen haben.

Nachdem Sie jedoch mehr von Ihrem Code gesehen haben, scheinen Sie wirklich Anti-Patterns zu verwenden. Ein Vorteil der Verwendung von Versprechen ist die Fehlerbehandlung. Für Ihren Fall benötigen Sie nur den folgenden Code:

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

Dies sollte ausreichen, um mit Ihrem Anwendungsfall fertig zu werden. Es ist viel klarer und es hat auch den Vorteil, dass really die Fehler korrekt verarbeitet.

23

Eine gute Antwort von Florian Für Ihre ursprüngliche Frage gibt es mehrere Möglichkeiten, eine Kette mit Bluebird zu beginnen.

Einer der einfachsten ist, Promise.resolve() in nichts aufzurufen:

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

oder

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

So können Sie tun:

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

Obwohl ich persönlich so etwas tun würde:

//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

Ich bin darauf gestoßen, als ich eine Methode hatte, die eine Ressource im Internet abruft und den Inhalt zurückgibt. Ich möchte jedoch, dass Verbindungs-Timeouts verarbeitet und bis zu X-mal mit Verzögerungen zwischen ihnen versucht wird.

Da Bluebird.defer veraltet ist, habe ich diesen Trick benutzt:

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

Ich finde ein Muster wie dieses nützlich für jegliche Art von Integrationstests.

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