Async: Unterstützung versprechen

Erstellt am 13. Nov. 2015  ·  22Kommentare  ·  Quelle: caolan/async

Fügen Sie Zusagen-Unterstützung hinzu, um verschiedene Aufgaben mischen zu können:

async.waterfall([
    function (done) {
        // Do something and call done()
        fs.readFile(filepath, done);
    },
    function(content) {
        // Do something and return Promise
        return mongoose.models.file.create({
            name: filepath,
            content: content
        });
    }
], (err) => {
    if (err) {
        console.error(err);
    }
});
feature

Hilfreichster Kommentar

Ich denke, genau wie es async.asyncify gibt, könnte es eine async.promisify-Funktion geben.

Dann kann ich einfach async.promisify(async.mapLimit(x,10, mapper)) abwarten.

Alle 22 Kommentare

asyncify nimmt eine synchrone Funktion, die ein Promise zurückgibt, und ruft einen Callback für ihre aufgelösten/abgelehnten Handler auf:

async.waterfall([
    function (done) {
        // Do something and call done()
        fs.readFile(filepath, done);
    },
    async.asyncify(function(content) {
        // Do something and return Promise
        return mongoose.models.file.create({
            name: filepath,
            content: content
        });
    })
], (err, model) => {
    if (err) {
        console.error(err);
    }
});

Aber diese Funktion ist nicht dokumentiert...

Ich hatte auch noch einen anderen Gedanken - sollten wir Funktionen, die Versprechen zurückgeben, automatisch asynchronisieren (oder sie entsprechend behandeln?). Was soll async tun, wenn eine ES-was auch immer async Funktion übergeben wird (die implizit ein Promise zurückgibt)?

z.B

async.waterfall([
    function (done) {
        // Do something and call done()
        fs.readFile(filepath, done);
    },
    async function(content) {
        return await mongoose.models.file.create({
            name: filepath,
            content: content
        });
    }
], (err, model) => {
    if (err) {
        console.error(err);
    }
});

Persönlich denke ich, dass Async Versprechen standardmäßig asynchronisieren sollte. Es gibt einige asynchrone Funktionen, die ich schreibe, die ich auch in async.queue einspeisen muss, aber ich möchte dies nicht schreiben:

import {queue, asyncify} from 'async'

const run = asyncify(async function () {
  await someStuff()
})

const q = async.queue(run)
q.push('asdf')

wo ich das schreiben könnte

import {queue} from 'async'

async function run () {
  await someStuff()
}

const q = async.queue(run)
q.push('asdf')

Die Dokumente für asyncify hinzugefügt. Ich werde dies für das automatische asynchronisierende Verhalten offen halten.

Darüber experimentierte ich mit der Verwendung derselben Codebasis und der Verwendung einer Promise-Schnittstelle für Methoden, die Callback als letzten Parameter verwenden. überprüfen Sie es !

async.waterfall([
  function (callback) {
    callback(null, 'one', 'two')
  },
  function (arg1, arg2, callback) {
    // arg1 now equals 'one' and arg2 now equals 'two'
    callback(null, 'three')
  },
  function (arg1, callback) {
    // arg1 now equals 'three'
    callback(null, 'done')
  }
]).then(function (value) {
  console.log(value === 'done')
})

was denkst du darüber? Ich denke, das könnte leicht sein, die Bibliothek anzupassen. Sehen Sie zum Beispiel, wie funktioniert das Bibliothekshandle cb und das Versprechen .

Sehr interessant. Wenn Async Funktionen, die Versprechen zurückgeben, richtig behandelt, dann könnte es auch versprochene Async-Funktionen ziemlich leicht akzeptieren. Das würde funktionieren:

async.parallel([
  async.waterfall([
    asyncFn1,
    function (result1, next) {
      //...
    }
    asyncFn2,
    //...
  ]), // no callback!
  async.each(arr, function (item, cb) {
    //...
  })
  otherAsyncFn
], done)

Es wäre viel einfacher, Async-Funktionen zu kombinieren.

Das Problem heute ist, dass Rückrufe optional sind. Wenn Sie das letzte Argument weglassen, wird die Aufgabe dennoch ausgeführt. Ich würde gerne machen, dass Async-Funktionen automatisch gecurry werden - wenn Sie den Rückruf weglassen, wird die Funktion teilweise angewendet, und Sie müssen sie nur mit einem Rückruf aufrufen. Aber da viele Methoden optionale Parameter haben und wir generell zu optionalen Callbacks übergehen, können Sie das nicht wirklich tun. Unsere Methoden sind variadisch, und Sie können keine variadischen Funktionen verwenden.

Wenn jedoch der letzte Rückruf von einer Methode weggelassen wird, muss sie ein Promise zurückgeben und wenn Async so eingerichtet ist, dass Funktionen verarbeitet werden, die Promises zurückgeben, ist dies eine interessante Kombination. Ein Hauptproblem ist dann, dass Async in eine Promise-Bibliothek integriert werden muss – welche? Verlassen wir uns auf global.Promise , was ältere Engines zum Polyfill zwingt, oder verwenden wir etwas wie Bluebird? Außerdem ist Async eine Art Aussage gegen Versprechen – Funktionen höherer Ordnung für Funktionen, die Rückrufe akzeptieren, anstatt das Futures-Paradigma zu übernehmen. Ich bin ganz für Interoperabilität mit Promises, aber ich denke, dass Async-Return-Versprechen etwas außerhalb seiner Designphilosophie liegen.

@aearly

Ich glaube, dass Promises ein Workflow ist, der auf die letzten Knotenversionen (>=4) ausgerichtet ist. In diesen Versionen sind Promises verfügbar, daher ist meine Vision, den Promise-Workflow zu verwenden, wenn die globale Umgebung Promises hat.

Es ist möglich, ein kleines Polyfill hinzuzufügen ( siehe Pinkie-Promise ), aber meiner Meinung nach ist es nicht sinnvoll, ein Polyfill bereitzustellen. Erzwingen Sie besser, dass der Benutzer die Knotenversion aktualisiert, um die letzten Knotenfunktionen zu verwenden. Wirklich, überprüfen Sie (bekommen 6 PR)[https://github.com/sindresorhus/got/pull/140]. Abhängigkeiten sind in sehr kleinen Projekten nicht erwünscht und werden überall verwendet.

Vielleicht könnte dieses Feature nach der asynchronen Modularisierung integriert werden, damit die Codebasis einfacher anzupassen ist.

Aber asynchron mit Versprechen auszurichten ist definitiv ein _must_!

@Kikobeats :+1:

Promises werden zu erstklassigen asynchronen Funktionen. Daher ist es schwer vorstellbar, dass die Bibliothek für die Asynchronität ohne ihre vollständige Unterstützung benötigt wird.

Ich denke, es könnte ohne Polyfill, aber mit Feature-Erkennung implementiert werden: Erlaube, wenn es ein globales Promise-Objekt mit der Methode resolve .

@aearly bluebird fügt der Liste der Polyfilling-Funktionen Browser-Kompatibilität hinzu. Ich denke, es könnte angebracht sein, es zu verwenden.

@martinheidegger Bluebird ist dafür zu groß. Es wird 76 KB (minifiziert) zur einfachen Unterstützung von Promise-Methoden werfen.

Auch hier ist die Verwendung der Callback- oder Promises-Schnittstelle in Ihrem Back-End-Workflow ein natürlicher Prozess, der auf Ihrer Knotenversion basiert.

  • Wenn Sie ein Backend mit mehr Zeit haben (vielleicht 2 Jahre oder länger), verwenden Sie die Version 0.10 oder 0.12 , sodass Ihr Code im Callback-Stil geschrieben ist.
  • Wenn Ihr Backend weniger als ~6 Monate hat und Sie die Knotenversion >=4 , verwenden Sie wahrscheinlich einen Promise-Stil.

Aber auf jeden Fall hast du keinen gemischten Stil.

Es ist also nicht notwendig, eine Abhängigkeit für Support-Versprechen hinzuzufügen; Wenn async eines Tages in der Zukunft Promises unterstützt, können Sie es verwenden, wenn Ihre Knotenversion Promises unterstützt.

Extremfall: _Ich verwende eine ältere Node-Version, aber mein Backend ist im Promises-Stil geschrieben_. Dann haben Sie ein Promises-Objekt als global definiert oder

Gleiches Verhalten für die Frontend-Seite. Abhängigkeit ist nicht notwendig.

Hmmn, es scheinen die gleichen Probleme zu gelten, die Versprechen vor 4-5 Jahren hatten. Wenn alle Node 4 oder höher und moderne Browser mit ES6-Unterstützung verwenden würden, könnten wir Versprechungen gegebenenfalls intern problemlos nutzen.

Das Problem ist, dass wir unsere Knoten 0.12 und ältere Browserbenutzer im Staub lassen und sie polyfillen müssen. Welche Polyfill verwenden sie? Wir würden keines bündeln wollen, selbst kleine Versprechungen haben Gewicht. Außerdem werden Leute, die Promises außerhalb des Standard-ES6-Promise verwenden, bluebird oder q usw. verwenden wollen, was auch immer sie verwenden. Ich möchte nicht die Verwendung eines Polyfills erfordern - npm i -S async sollte alles sein, was die Leute tun müssen.

Async war auch eine Art Reaktion auf Promises – eine alternative Möglichkeit, asynchronen Code zu verwalten. Die Verwendung von Promises scheint ein Schritt zurück zu sein. Korrekt verwaltete Callbacks können genauso leistungsfähig sein wie Promises (und in vielen Fällen schneller, da Promises über eine integrierte Event-Loop-Verzögerung verfügen).

Ich bin ganz für Interop mit Promises, wenn einer Funktion ein Promise oder ein anderes "Dannable" übergeben wird, sollten wir es auf jeden Fall nutzen. Aber ich denke, wir sollten vermeiden, Versprechen intern zu erstellen und/oder zurückzugeben, nur weil die plattformübergreifende ES6-Unterstützung noch einen Weg vor sich hat.

Zugegeben, Versprechen sind nicht billig zu erstellen oder zu verarbeiten. Ich würde so etwas eher als Opt-in-Erweiterung sehen. Versprechen sind toll, aber du wirst sie nicht immer wollen

IMHO, nachdem ich viel Node-Code zu Promises + Co + Yield migriert hatte, fand ich keinen direkten Ersatz nur für .eachLimit() . Wahrscheinlich ist die Liste der nützlichen Fälle viel geringer als auf den ersten Blick und kann mit einem separaten Paket behandelt werden.

Ich mag die kleine Erweiterung von @Kikobeats , es kann sinnvoll sein, sie in der Readme (/cc @aearly) zu empfehlen.

Ich wäre aus Gründen, die von mir selbst und anderen Benutzern vorgebracht wurden, entschieden gegen die offizielle Unterstützung von async-Versprechen.

@megawac Was ist mit dem Fall, in dem eine Funktion ein Versprechen zurückgibt? zB @SEAPUNK 's Beispiel.

@megawac Ich habe Unterstützung für Callback-Stil, Tests und Browser-Build in Promise- Async hinzugefügt. Wenn dann jemand Promise verwenden möchte, denke ich, dass das bereit ist :+1:

@aearly , das wäre in Ordnung, nehme ich an (so =), aber ich würde es lieber im Plugin lassen
persönlich landen

Am Freitag, 22. Januar 2016 um 14:17 Uhr, Kiko Beats [email protected]
schrieb:

@megawac https://github.com/megawac I Unterstützung für Rückrufstil hinzugefügt
und testet auf Promise-Async
https://github.com/Kikobeats/promise-async#promise-async . Dann wenn
jeder möchte Promise verwenden, ich denke, das ist fertig [image: :+1:]


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/caolan/async/issues/956#issuecomment -174016628.

Hier ist ein weiteres Paket, das alle verfügbaren asynchronen Methoden verspricht:
https://github.com/eladnava/koa-async

Ich denke, genau wie es async.asyncify gibt, könnte es eine async.promisify-Funktion geben.

Dann kann ich einfach async.promisify(async.mapLimit(x,10, mapper)) abwarten.

Ich würde dem nicht widersprechen, wenn Sie einen Pull-Request erstellen möchten

Am Samstag, 17. Dezember 2016 um 16:57 Uhr, Manoj Patel [email protected]
schrieb:

Ich denke, genau wie es async.asyncify gibt, könnte es async.promisify geben
Funktion.

Dann kann ich einfach async.promisify(async.mapLimit(x,10, mapper)) abwarten.


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/caolan/async/issues/956#issuecomment-267789633 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/ADUIEKJIDulPHAn_SeEZbiPb3t7ORGnpks5rJFqvgaJpZM4Gh1fr
.

Ich verwende die promisifyAll- Methode des bluebird Moduls, um Rückrufe in Promises umzuwandeln, sodass die Methoden von async zu:

// adds '<original-method>Async' to class 
Promise.promisifyAll(async);

function somePromise() {
    return async.parallelAsync([
        function(cb) {
            setTimeout(function(){
                cb(new Error('err'), 'foo')
            }, 1000);
        },
        function(cb) {
            setTimeout(function(){
                cb(null, 'bar')
            }, 1000);
        }
    ]);
}

somePromise().then(function(result){
    console.log('result',result);
}).catch(function(err){
    console.log('err',err);
});

JSFiddle-Beispiel

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen