Async: Janji dukungan

Dibuat pada 13 Nov 2015  ·  22Komentar  ·  Sumber: caolan/async

Tambahkan dukungan janji untuk memungkinkan campuran tugas yang berbeda:

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

Komentar yang paling membantu

Saya pikir seperti ada async.asyncify mungkin ada fungsi async.promisify.

Lalu saya bisa menunggu async.promisify(async.mapLimit(x,10, mapper))

Semua 22 komentar

asyncify akan mengambil fungsi sinkron yang mengembalikan Janji dan memanggil panggilan balik pada penangan yang diselesaikan/ditolak:

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

Tapi fitur itu tidak didokumentasikan...

Saya juga punya pemikiran lain -- haruskah kita secara otomatis menyinkronkan fungsi yang mengembalikan janji (atau menanganinya dengan tepat?). Apa yang harus dilakukan async ketika melewati fungsi ES-apapun async (yang secara implisit mengembalikan janji)?

misalnya

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

Secara pribadi, saya pikir async harus menyinkronkan janji secara default. Ada beberapa fungsi async yang saya tulis yang juga harus saya masukkan ke async.queue, tetapi saya tidak ingin menulis ini:

import {queue, asyncify} from 'async'

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

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

dimana aku bisa menulis ini

import {queue} from 'async'

async function run () {
  await someStuff()
}

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

Menambahkan dokumen untuk asyncify . Akan tetap membuka ini untuk perilaku asinkronisasi otomatis.

Tentang ini, saya bereksperimen dengan menggunakan basis kode yang sama dan menggunakan antarmuka Promise untuk metode yang menggunakan panggilan balik sebagai parameter terakhir. periksa !

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')
})

apa yang Anda pikirkan? Saya pikir itu bisa mudah untuk mengadaptasi perpustakaan. Lihat misalnya bagaimana cara kerja perpustakaan menangani cb dan janji .

Sangat menarik. Jika Async menangani fungsi yang mengembalikan janji dengan benar, maka Async juga dapat menerima fungsi Async yang dijanjikan dengan cukup mudah. Ini akan berhasil:

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

Akan jauh lebih mudah untuk menggabungkan fungsi Async.

Masalahnya hari ini adalah bahwa panggilan balik adalah opsional. Meninggalkan argumen terakhir masih menjalankan tugas. Saya ingin membuatnya agar fungsi Async secara otomatis kari -- jika Anda meninggalkan panggilan balik, itu sebagian menerapkan fungsi tersebut, dan yang perlu Anda lakukan hanyalah memanggilnya dengan panggilan balik. Tetapi karena banyak metode memiliki parameter opsional, dan kami beralih ke callback opsional di seluruh papan, Anda tidak dapat benar-benar melakukannya. Metode kami adalah variadik, dan Anda tidak dapat menggunakan fungsi variadik.

Namun, jika meninggalkan panggilan balik terakhir dari suatu metode, metode itu mengembalikan Janji, dan jika Async diatur untuk menangani fungsi yang mengembalikan janji, adalah kombo yang menarik. Salah satu masalah utama adalah kemudian Async harus berintegrasi dengan perpustakaan janji -- yang mana? Apakah kita mengandalkan global.Promise , memaksa mesin lama untuk melakukan polyfill, atau apakah kita menggunakan sesuatu seperti Bluebird? Juga, Async adalah semacam pernyataan yang menentang janji - fungsi tingkat tinggi untuk fungsi penerimaan panggilan balik, daripada mengadopsi paradigma Futures. Saya setuju dengan interoperabilitas dengan Promises, tetapi saya pikir memiliki janji pengembalian Async sedikit di luar filosofi desainnya.

@aearly

Saya merasa bahwa Janji adalah alur kerja yang selaras dengan versi simpul terakhir (>=4). Dalam versi ini, Janji tersedia, jadi, visi saya adalah menggunakan alur kerja Janji ketika lingkungan global memiliki Janji.

Mungkin saja menambahkan polyfill kecil (periksa pinkie-promise ) tetapi menurut saya tidak masuk akal untuk memberikan polyfill. Lebih baik memaksa pengguna meningkatkan versi simpul untuk menggunakan fitur simpul terakhir. Sungguh, periksa (dapat 6 PR)[https://github.com/sindresorhus/got/pull/140]. Ketergantungan tidak diterima dalam proyek yang sangat kecil dan digunakan di mana-mana.

Mungkin fitur ini bagus untuk dimasukkan setelah modularisasi async, sehingga basis kode akan lebih mudah beradaptasi.

Tapi yang pasti, menyelaraskan async dengan janji benar-benar _harus_!

@Kikobeats :+1:

Promise menjadi fungsi async kelas satu. Jadi sulit untuk membayangkan perpustakaan yang harus diangkat untuk asinkron tanpa dukungan penuh dari mereka.

Saya pikir itu bisa diimplementasikan tanpa polyfill tetapi dengan deteksi fitur: izinkan jika ada objek Janji global dengan metode resolve .

@aearly bluebird menambahkan kompatibilitas browser ke daftar polyfilling. Saya pikir mungkin tepat untuk menggunakannya.

@martinheidegger Bluebird terlalu besar untuk ini. Ini akan menghasilkan 76 Kb (diperkecil) untuk dukungan sederhana dari metode janji.

Sekali lagi, gunakan antarmuka panggilan balik atau janji di alur kerja backend Anda adalah proses alami yang berbasis di versi simpul Anda.

  • Jika Anda memiliki backend waktu lebih (mungkin 2 tahun atau lebih), Anda menggunakan versi 0.10 atau 0.12 , jadi, kode Anda ditulis dalam gaya panggilan balik.
  • Jika backend Anda memiliki waktu kurang dari ~6 bulan dan Anda menggunakan versi node >=4 mungkin Anda menggunakan gaya Promise.

Tapi dalam hal apapun Anda tidak memiliki gaya campuran.

Jadi tidak perlu menambahkan ketergantungan untuk janji dukungan; Jika async mendukung janji suatu hari nanti, Anda dapat menggunakannya jika versi simpul Anda mendukung Janji.

Kasus ekstrem: _Saya menggunakan versi simpul yang lebih lama tetapi backend saya ditulis menggunakan gaya janji_. Kemudian Anda telah mendefinisikan objek Promises sebagai global atau mendefinisikannya sebelum menggunakan async . Apapun yang kamu mau. Secara sederhana.

Perilaku yang sama untuk sisi frontend. Tidak perlu ketergantungan.

Hmm, sepertinya masalah yang sama Janji 4-5 tahun yang lalu masih berlaku. Jika semua orang menggunakan node 4 atau lebih baru, dan browser modern dengan dukungan ES6, kami dapat dengan mudah memanfaatkan janji secara internal jika berlaku.

Masalahnya adalah kita meninggalkan node 0.12 dan pengguna browser yang lebih tua dalam debu, mengharuskan mereka untuk polyfill. Polyfill mana yang mereka gunakan? Kami tidak ingin membundel satu, bahkan janji kelingking memiliki bobot untuk itu. Juga, orang yang menggunakan janji di luar Janji ES6 standar akan ingin menggunakan bluebird atau q dll., apa pun yang mereka gunakan. Saya tidak ingin mengharuskan penggunaan polyfill -- npm i -S async harus dilakukan oleh semua orang.

Async juga merupakan reaksi terhadap Promises -- cara alternatif untuk mengelola kode asinkron. Untuk mulai menggunakan Promises sepertinya merupakan langkah mundur dari itu. Panggilan balik yang dikelola dengan benar bisa sama kuatnya dengan janji (dan dalam banyak kasus, lebih cepat, karena Janji memiliki penangguhan loop peristiwa bawaan).

Saya siap untuk interop dengan janji, jika suatu fungsi dilewatkan Janji atau "yang dapat" lainnya daripada kita pasti harus memanfaatkannya. Tapi saya pikir kita harus menghindari membuat dan/atau mengembalikan Janji secara internal, hanya karena fakta dukungan ES6 di seluruh platform masih memiliki cara untuk pergi.

Setuju, janji tidak murah untuk dibuat atau diproses. Saya lebih suka melihat sesuatu seperti ini sebagai ekstensi keikutsertaan. Janji memang bagus tapi kamu tidak akan selalu menginginkannya

IMHO, setelah memigrasi banyak kode simpul ke janji + co + hasil, saya tidak menemukan pengganti langsung hanya untuk .eachLimit() . Mungkin, daftar kasus yang berguna jauh lebih sedikit daripada yang terlihat pada pandangan pertama, dan dapat ditangani dengan paket terpisah.

Saya suka ekstensi kecil @Kikobeats , mungkin masuk akal untuk merekomendasikannya di readme (/cc @aearly).

Saya akan sangat menentang dukungan resmi janji di async karena alasan yang diajukan oleh saya sendiri dan pengguna lain.

@megac Bagaimana dengan kasus di mana suatu fungsi mengembalikan janji? misalnya @SEAPUNK 's contoh.

@megawac Saya Menambahkan dukungan untuk gaya panggilan balik, pengujian, dan build browser di promise-async . Lalu jika ada yang ingin menggunakan Promise, saya rasa sudah siap :+1:

@aearly , saya kira tidak apa-apa (jadi =) tapi saya lebih suka membiarkannya di plugin
mendarat secara pribadi

Pada Jumat, 22 Jan 2016 pukul 14:17, Kiko Beats [email protected]
menulis:

@megawac https://github.com/megawac Saya Menambahkan dukungan untuk gaya panggilan balik
dan tes untuk janji-async
https://github.com/Kikobeats/promise-async#promise -async. Lalu jika
ada yang mau pakai Promise, saya rasa sudah ready [image: :+1:]


Balas email ini secara langsung atau lihat di GitHub
https://github.com/caolan/async/issues/956#issuecomment -174016628.

Berikut paket lain yang menjanjikan semua metode async yang tersedia:
https://github.com/eladnava/koa-async

Saya pikir seperti ada async.asyncify mungkin ada fungsi async.promisify.

Lalu saya bisa menunggu async.promisify(async.mapLimit(x,10, mapper))

Saya tidak akan keberatan jika Anda ingin membuat permintaan tarik

Pada Sat, 17 Desember 2016 di 04:57, Manoj Patel [email protected]
menulis:

Saya pikir seperti ada async.asyncify, mungkin ada async.promisify
fungsi.

Lalu saya bisa menunggu async.promisify(async.mapLimit(x,10, mapper))


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/caolan/async/issues/956#issuecomment-267789633 , atau bisu
benang
https://github.com/notifications/unsubscribe-auth/ADUIEKJIDulPHAn_SeEZbiPb3t7ORGnpks5rJFqvgaJpZM4Gh1fr
.

Saya menggunakan metode promisifyAll modul bluebird untuk mengubah panggilan balik menjadi janji sehingga metode async menjadi:

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

Contoh JSFiddle

Apakah halaman ini membantu?
0 / 5 - 0 peringkat