Async: Dukungan Fungsi `async`

Dibuat pada 16 Mar 2017  ·  10Komentar  ·  Sumber: caolan/async

Salah satu keunggulannya adalah dukungan async / await baru yang telah hadir di Node dan Chrome, dan akan segera hadir di setiap browser utama lainnya. Saya telah memikirkan tentang apa yang dapat dilakukan Async di dunia async / await .

Saat ini, kita dapat mengadaptasi fungsi async dengan membungkusnya dengan asyncify . Karena fungsi async pada dasarnya hanya fungsi yang mengembalikan Janji, adaptor lama itu dapat dengan mudah mengubahnya menjadi fungsi gaya panggilan balik. Namun, itu mengarah pada tampilan yang agak tidak masuk akal:

async.mapLimit(arr, 10, async.asyncify(async (val) => {
  let foo = await doSomething(val);
  //...
 return bar;
}), done);

Namun, salah satu fitur dalam spesifikasi fungsi async adalah:

Object.getPrototypeOf(asyncFn)[Symbol.toStringTag] === "AsyncFunction"

Ini memberikan cara untuk dengan mudah mendeteksi (asli) fungsi async . Kita bisa menggunakan teknik ini untuk secara otomatis asyncify mereka. Contoh di atas menjadi:

async.mapLimit(arr, 10, async (val) => {
  let foo = await doSomething(val);
  //...
 return bar;
}, done);

...yang tampaknya mengalir lebih alami. Saya juga berpikir kita harus terus menggunakan callback. Jika pengguna ingin await hasilnya, mereka harus promisify fungsi, atau pify Async secara keseluruhan:

let result = await pify(async.mapLimit)(arr, 10, async (val) => {
  let foo = await doSomething(val);
  //...
 return bar;
});

Metode di atas untuk mendeteksi fungsi async hanya berfungsi dengan fungsi asli. Saya tidak berpikir ada cara untuk mendeteksi fungsi Babel yang diubah. Kami tentu saja tidak dapat mendeteksi fungsi normal yang hanya mengembalikan Janji, karena kami harus secara surut tidak meneruskan panggilan balik. Akan ada peringatan besar bahwa ini hanya akan berfungsi tanpa transpiler di lingkungan yang sangat modern, jika tidak, Anda masih harus membungkus secara manual dengan asyncify .

Juga, memang, banyak metode Async tidak masuk akal dengan async / await . Sebagian besar metode aliran kontrol (kecuali untuk hal-hal seperti auto dan queue ) lebih mudah direplikasi dengan konstruksi aliran kontrol asli. map dan parallel dapat diganti dengan Promise.map dan Promise.all . Namun, fungsi koleksi yang membatasi akan sangat berguna, serta auto dan beberapa lainnya. (Juga, autoInject dengan fungsi async adalah mimpi aliran kontrol asinkron!)

enhancement feedback-wanted

Komentar yang paling membantu

Apakah ada alasan untuk melakukan Object.getPrototypeOf(asyncFn)[Symbol.toStringTag] === "AsyncFunction" atau dapatkah kita melakukan asyncFn[Symbol.toStringTag] === "AsyncFunction" (tampaknya berfungsi di FF)?

Itu hanya cara spesifikasi ECMA kanonik untuk melakukannya. Saya kira secara teori, seseorang dapat menimpa asyncFn[Symbol.toStringTag] .

Begitu juga proposal setiap kali seseorang memberikan panggilan balik dengan format cb(err, arg) kita harus mendeteksi jika itu adalah AsyncFunction; jika itu adalah fungsi async, kita harus menerapkan promisify jika tidak, gunakan apa adanya

Saya pikir Anda memilikinya sedikit ke belakang. Di mana pun kita menerima fungsi iteratee yang menerima panggilan balik ( function(args..., callback) {} ), kita harus memeriksa untuk melihat apakah itu adalah fungsi async , dan kemudian asyncify itu.

Contoh await adalah apa yang akan dilakukan seseorang jika mereka ingin await metode Async. Saya tidak berpikir kita harus memiliki metode Async mulai mengembalikan janji sehingga akan berhasil - biarkan pengguna melakukannya.

Semua 10 komentar

Saya akan merenungkan ini lagi, tetapi saya ingin mengajukan beberapa pertanyaan teknis agar saya dapat mencoba membayangkan dengan lebih baik seperti apa ini..

Apakah ada alasan untuk melakukan Object.getPrototypeOf(asyncFn)[Symbol.toStringTag] === "AsyncFunction" atau dapatkah kita melakukan asyncFn[Symbol.toStringTag] === "AsyncFunction" (tampaknya berfungsi di FF)?

Begitu juga proposal setiap kali seseorang memberikan panggilan balik dengan format cb(err, arg) kita harus mendeteksi jika itu adalah AsyncFunction ; jika ini adalah fungsi async, kita harus menerapkan promisify jika tidak, gunakan apa adanya

Maaf juga, saya tidak mengikuti contoh menunggu, jika kami mendeteksi bahwa fungsinya adalah AsyncFunction apa tantangan untuk mendukung await ?

Apakah ada alasan untuk melakukan Object.getPrototypeOf(asyncFn)[Symbol.toStringTag] === "AsyncFunction" atau dapatkah kita melakukan asyncFn[Symbol.toStringTag] === "AsyncFunction" (tampaknya berfungsi di FF)?

Itu hanya cara spesifikasi ECMA kanonik untuk melakukannya. Saya kira secara teori, seseorang dapat menimpa asyncFn[Symbol.toStringTag] .

Begitu juga proposal setiap kali seseorang memberikan panggilan balik dengan format cb(err, arg) kita harus mendeteksi jika itu adalah AsyncFunction; jika itu adalah fungsi async, kita harus menerapkan promisify jika tidak, gunakan apa adanya

Saya pikir Anda memilikinya sedikit ke belakang. Di mana pun kita menerima fungsi iteratee yang menerima panggilan balik ( function(args..., callback) {} ), kita harus memeriksa untuk melihat apakah itu adalah fungsi async , dan kemudian asyncify itu.

Contoh await adalah apa yang akan dilakukan seseorang jika mereka ingin await metode Async. Saya tidak berpikir kita harus memiliki metode Async mulai mengembalikan janji sehingga akan berhasil - biarkan pengguna melakukannya.

Diimplementasikan pada #1390 !

Ini adalah perubahan yang melanggar dan memecahkan kode yang kami terapkan. Harap berpikir dua kali ketika melakukan hal-hal seperti itu tanpa meningkatkan versi utama.

PS: terima kasih untuk semua pekerjaan hebat yang Anda lakukan dengan perpustakaan ini

Menembak! Apa yang rusak. Bisakah Anda membuatkan tiket dengan detail
lingkungan ini tidak berhasil?
Terima kasih!

Pada Rabu, 5 Apr 2017 pukul 10:18 Manuel Valls Fernández <
[email protected]> menulis:

Ini adalah perubahan yang melanggar dan memecahkan kode yang kami terapkan. Tolong pikirkan dua kali
ketika melakukan hal-hal seperti itu tanpa meningkatkan versi utama.

PS: terima kasih untuk semua pekerjaan hebat yang Anda lakukan dengan perpustakaan ini


Anda menerima ini karena Anda berkomentar.
Balas email ini secara langsung, lihat di GitHub
https://github.com/caolan/async/issues/1386#issuecomment-291875817 , atau bisukan
benang
https://github.com/notifications/unsubscribe-auth/ADUIEPNKTSOVuuiwucBVrH983X6B568Wks5rs6K3gaJpZM4Mf64R
.

Setuju, itu merusak bangunan saya juga ...

Air terjun yang memanggil fungsi async yang berfungsi beberapa hari yang lalu mulai gagal dengan "cb tidak berfungsi" karena panggilan balik async tidak lagi disediakan untuk fungsi tersebut.

Maaf kami memecahkan kode Anda. Kami tidak mengantisipasi kasus penggunaan Anda untuk fungsi async . Saya akan merekomendasikan memutar kembali ke 2.2.0, atau memfaktorkan ulang kode Anda menjadi return nilai yang Anda butuhkan, daripada menggunakan panggilan balik. Sayangnya, kucing keluar dari kantong dengan fitur ini, jadi kami tidak bisa mundur.

@aearly Tolong, jangan sebutkan!! Anda sangat baik untuk menjawab :1st_place_medal:

@manvalls memberi saya solusi hebat yang tidak perlu melakukan rollback. Saat Anda menggunakan simbol untuk mendeteksi async dalam deklarasi fungsi, dia memikirkan cara cerdas untuk menipu deteksi.

Air terjun saya menggunakan fungsi yang diekspor dari modul lain, salah satunya adalah async dan dengan demikian menyebabkan kegagalan.

Jadi hanya dengan mengubah dari:

... 
/* services module */
function doThis(param, cb) {
...
}

async function doThatAsync(param, cb) {
...
}

module.exports = {
  doThis: doThis,
  doThat: doThatAsync  
}; 

...
async.waterfall([
  services.doThis,
  services.doThat,  // fails with "cb is not a function"
], err => {
...
}

Ke:

... 
/* services module */
function doThis(param, cb) {
...
}

async function doThatAsync(param, cb) {
...
}

module.exports = {
  doThis: doThis,
  doThat: (...args) => doThatAsync(..args)   // cheating the detection
}; 

...
async.waterfall([
  services.doThis,
  services.doThat, /* it works!!! */
], err => {
...
}

Terima kasih banyak lagi

dapatkah kita menggunakan async/menunggu dengan async.autoInject()?

async.autoInject({

    conn1: async function () {
      return conn1;
    },

    conn2: async function () {
      return conn2;
    },
});

sepertinya tidak berhasil, saya mendapatkan:

Kesalahan: fungsi tugas AutoInject memerlukan parameter eksplisit.
di /Users/alexamil/WebstormProjects/nabisco/cdt-now/node_modules/async/dist/async.js:2081:23
di /Users/alexamil/WebstormProjects/nabisco/cdt-now/node_modules/async

@ORESoftware ya, fungsi async harus bekerja dengan autoInject . Saya menguji kode yang Anda posting di Chrome, dan itu berjalan. Saya mendapat ReferenceError dalam panggilan balik terakhir karena conn1 dan conn2 adalah undefined . Setelah diubah menjadi

async.autoInject({
    conn1: async function () {
      return 'foo'
    },
    conn2: async function () {
      return 'bar'
    },
})

itu bekerja dengan baik. Namun, kami tidak mendukung fungsi async yang ditranspilasikan. Apakah Anda menerjemahkan kode Anda?

Apakah halaman ini membantu?
0 / 5 - 0 peringkat