Bagaimana cara menggabungkan panggilan fungsi asinkron menjadi fungsi sinkronisasi di Node.js atau Javascript?

122

Misalkan Anda mempertahankan pustaka yang mengekspos suatu fungsi getData. Pengguna Anda menyebutnya untuk mendapatkan data aktual:
var output = getData();
Di balik terpal data disimpan dalam file sehingga Anda menerapkannya getDatamenggunakan Node.js bawaan fs.readFileSync. Sudah jelas keduanya getDatadan fs.readFileSyncmerupakan fungsi sinkronisasi. Suatu hari Anda diminta untuk mengalihkan sumber data yang mendasari ke repo seperti MongoDB yang hanya dapat diakses secara asinkron. Anda juga diberitahu untuk menghindari membuat pengguna Anda kesal, getDataAPI tidak dapat diubah untuk hanya mengembalikan sebuah janji atau meminta parameter callback. Bagaimana Anda memenuhi kedua persyaratan tersebut?

Fungsi asynchronous menggunakan callback / promise adalah DNA JavasSript dan Node.js. Aplikasi JS non-sepele apa pun mungkin diresapi dengan gaya pengkodean ini. Tapi praktik ini dapat dengan mudah mengarah pada apa yang disebut piramida malapetaka panggilan balik. Lebih buruk lagi, jika kode apa pun di pemanggil mana pun dalam rantai panggilan bergantung pada hasil dari fungsi asinkron, kode tersebut harus dibungkus dalam fungsi panggilan balik juga, sehingga menerapkan batasan gaya pengkodean pada pemanggil. Dari waktu ke waktu saya merasa perlu untuk merangkum fungsi async (sering disediakan di perpustakaan pihak ke-3) ke dalam fungsi sinkronisasi untuk menghindari pemfaktoran ulang global secara besar-besaran. Mencari solusi tentang masalah ini biasanya berakhir dengan Node Fibers atau paket npm yang diturunkan darinya. Tapi Serat tidak bisa menyelesaikan masalah yang saya hadapi. Bahkan contoh yang diberikan oleh penulis Fibers menggambarkan kekurangannya:

...
Fiber(function() {
    console.log('wait... ' + new Date);
    sleep(1000);
    console.log('ok... ' + new Date);
}).run();
console.log('back in main');

Output aktual:

wait... Fri Jan 21 2011 22:42:04 GMT+0900 (JST)
back in main
ok... Fri Jan 21 2011 22:42:05 GMT+0900 (JST)

Jika fungsi Fiber benar-benar mengubah fungsi async menjadi sinkron, outputnya harus:

wait... Fri Jan 21 2011 22:42:04 GMT+0900 (JST)
ok... Fri Jan 21 2011 22:42:05 GMT+0900 (JST)
back in main

Saya telah membuat contoh sederhana lainnya di JSFiddle dan mencari kode untuk menghasilkan keluaran yang diharapkan. Saya akan menerima solusi yang hanya berfungsi di Node.js sehingga Anda bebas memerlukan paket npm apa pun meskipun tidak berfungsi di JSFiddle.

abbr
sumber
2
Fungsi asinkron tidak pernah bisa dibuat sinkron di Node, dan meskipun bisa, Anda tidak boleh melakukannya. Masalahnya adalah di modul fs Anda dapat melihat fungsi yang benar-benar terpisah untuk akses sinkron dan asinkron ke sistem file. Hal terbaik yang dapat Anda lakukan adalah menutupi tampilan async dengan promise atau coroutine (generator di ES6). Untuk mengelola piramida panggilan balik, beri mereka nama alih-alih menentukan dalam panggilan fungsi, dan gunakan sesuatu seperti pustaka asinkron.
qubyte
8
Untuk dandavis, asinkron meningkatkan detail implementasi ke rantai panggilan, terkadang memaksa pemfaktoran ulang global. Ini merugikan dan bahkan bencana untuk aplikasi kompleks di mana modularisasi dan penahanan penting.
abbr
4
"Callback pyramid of doom" hanyalah representasi dari masalah. Promise dapat menyembunyikan atau menyamarkannya tetapi tidak dapat mengatasi tantangan sebenarnya: Jika pemanggil fungsi async bergantung pada hasil fungsi asinkron, ia harus menggunakan callback, begitu pula pemanggilnya, dll. Ini adalah contoh klasik dari memaksakan batasan untuk pemanggil hanya karena detail implementasi.
abbr
1
@abbr: Terima kasih untuk modul deasync, deskripsi masalah Anda persis seperti yang saya cari, dan tidak dapat menemukan solusi yang bisa diterapkan. Saya mengotak-atik generator dan iterable, tetapi sampai pada kesimpulan yang sama seperti Anda.
Kevin Jhangiani
2
Perlu dicatat bahwa hampir tidak pernah merupakan ide yang baik untuk memaksa fungsi asinkron agar disinkronkan. Anda hampir selalu memiliki solusi yang lebih baik yang menjaga asinkronisasi fungsi tetap utuh, sambil tetap mencapai efek yang sama (seperti pengurutan, pengaturan variabel, dll).
Hantu Madara

Jawaban:

104

deasync mengubah fungsi asinkron menjadi sinkron, diimplementasikan dengan mekanisme pemblokiran dengan memanggil event loop Node.js pada lapisan JavaScript. Akibatnya, deasync hanya memblokir kode berikutnya agar tidak berjalan tanpa memblokir seluruh utas, atau membuat menunggu sibuk. Dengan modul ini, berikut adalah jawaban dari tantangan jsFiddle:

function AnticipatedSyncFunction(){
  var ret;
  setTimeout(function(){
      ret = "hello";
  },3000);
  while(ret === undefined) {
    require('deasync').runLoopOnce();
  }
  return ret;    
}


var output = AnticipatedSyncFunction();
//expected: output=hello (after waiting for 3 sec)
console.log("output="+output);
//actual: output=hello (after waiting for 3 sec)

(Penafian: Saya adalah penulis bersama deasync. Modul ini dibuat setelah memposting pertanyaan ini dan tidak menemukan proposal yang bisa diterapkan.)

abbr
sumber
Adakah orang lain yang beruntung dengan ini? Saya tidak bisa membuatnya bekerja.
Newman
3
Saya tidak bisa membuatnya bekerja dengan baik. Anda harus meningkatkan dokumentasi Anda untuk modul ini, jika Anda ingin agar lebih banyak digunakan. Saya ragu penulis tahu persis apa konsekuensi dari penggunaan modul, dan jika mereka melakukannya, mereka pasti tidak mendokumentasikannya.
Alexander Mills
5
Sejauh ini ada satu masalah yang dikonfirmasi yang didokumentasikan di pelacak masalah github. Masalah telah diperbaiki di Node v0.12. Sisanya yang saya tahu hanyalah spekulasi tak berdasar yang tidak layak untuk didokumentasikan. Jika Anda yakin masalah Anda disebabkan oleh deasync, posting skenario mandiri dan dapat diduplikasi dan saya akan memeriksanya.
abbr
Saya mencoba menggunakannya dan saya mendapatkan beberapa perbaikan dalam skrip saya tetapi tetap saya tidak beruntung dengan tanggalnya. Saya memodifikasi kode sebagai berikut: function AnticipatedSyncFunction(){ var ret; setTimeout(function(){ var startdate = new Date() //console.log(startdate) ret = "hello" + startdate; },3000); while(ret === undefined) { require('deasync').runLoopOnce(); } return ret; } var output = AnticipatedSyncFunction(); var startdate = new Date() console.log(startdate) console.log("output="+output); dan saya berharap melihat 3 detik berbeda dalam keluaran tanggal!
Alex
@abbr dapatkah ini dijelajahi dan digunakan tanpa ketergantungan node>
Gandhi
5

Ada juga modul sinkronisasi npm. yang digunakan untuk menyinkronkan proses menjalankan kueri.

Ketika Anda ingin menjalankan query paralel secara sinkron maka node membatasi untuk melakukan itu karena tidak pernah menunggu respon. dan modul sinkronisasi sangat cocok untuk solusi semacam itu.

Kode sampel

/*require sync module*/
var Sync = require('sync');
    app.get('/',function(req,res,next){
      story.find().exec(function(err,data){
        var sync_function_data = find_user.sync(null, {name: "sanjeev"});
          res.send({story:data,user:sync_function_data});
        });
    });


    /*****sync function defined here *******/
    function find_user(req_json, callback) {
        process.nextTick(function () {

            users.find(req_json,function (err,data)
            {
                if (!err) {
                    callback(null, data);
                } else {
                    callback(null, err);
                }
            });
        });
    }

tautan referensi: https://www.npmjs.com/package/sync

sanjeev kumar
sumber
4

Jika fungsi Fiber benar-benar mengubah fungsi async tidur menjadi sinkron

Iya. Di dalam serat, fungsi menunggu sebelum masuk ok. Serat tidak membuat fungsi asinkron sinkron, tetapi memungkinkan untuk menulis kode tampak sinkron yang menggunakan fungsi asinkron dan kemudian akan berjalan secara asinkron di dalam file Fiber.

Dari waktu ke waktu saya merasa perlu untuk merangkum fungsi async menjadi fungsi sinkronisasi untuk menghindari pemfaktoran ulang global yang masif.

Kamu tidak bisa. Tidak mungkin untuk membuat kode asinkron sinkron. Anda perlu mengantisipasi hal itu dalam kode global Anda, dan menulisnya dengan gaya async dari awal. Apakah Anda membungkus kode global dalam fiber, menggunakan promise, generator promise, atau callback sederhana bergantung pada preferensi Anda.

Tujuan saya adalah untuk meminimalkan dampak pada pemanggil ketika metode akuisisi data diubah dari sinkronisasi ke asinkron

Baik janji maupun serat dapat melakukannya.

Bergi
sumber
1
ini adalah hal terburuk MUTLAK yang dapat Anda lakukan dengan Node.js: "kode yang tampak sinkron yang menggunakan fungsi asinkron dan kemudian akan berjalan secara tidak sinkron." jika API Anda melakukan itu, Anda akan menghancurkan kehidupan. jika asynchronous, itu harus memerlukan callback, dan memunculkan error jika tidak ada callback yang disediakan. itulah cara terbaik untuk membuat API, kecuali jika tujuan Anda adalah menipu orang.
Alexander Mills
@AlexMills: Ya, itu memang mengerikan . Namun, untungnya tidak ada yang bisa dilakukan API. API asinkron selalu perlu menerima callback / mengembalikan janji / berharap untuk dijalankan di dalam fiber - itu tidak akan bekerja tanpanya. Afaik, serat kebanyakan digunakan dalam skrip quick'n'dirty yang memblokir dan tidak memiliki konkurensi apa pun, tetapi ingin menggunakan API asinkron; seperti di node terkadang ada kasus di mana Anda akan menggunakan fsmetode sinkron .
Bergi
2
Saya biasanya suka node. Apalagi jika saya bisa menggunakan skrip bukan murni js. Tapi seluruh omong kosong asinkron yang meresap ke semua yang Anda lakukan dan benar-benar menginfeksi setiap fungsi dalam rantai panggilan segera setelah Anda memutuskan untuk membuat satu panggilan asinkron adalah sesuatu yang saya sangat ... sangat benci. Async api seperti penyakit menular, satu panggilan menginfeksi seluruh basis kode Anda memaksa Anda untuk menulis ulang semua kode yang Anda miliki. Saya benar-benar tidak mengerti bagaimana orang bisa membantah ini adalah hal yang baik .
Kris
@Kris Naskah menggunakan model asinkron untuk tugas-tugas IO karena cepat dan sederhana. Anda juga dapat melakukan banyak hal secara bersamaan, tetapi pemblokirannya lambat karena Anda tidak dapat melakukan apa pun secara bersamaan - kecuali jika Anda mencari utas, yang membuat semuanya menjadi rumit.
Bergi
@Bergi Saya membaca manifesto jadi saya tahu argumennya. Tetapi mengubah kode yang ada menjadi asinkron saat Anda menekan panggilan api pertama yang tidak memiliki padanan sinkronisasi tidaklah mudah. Semuanya rusak dan setiap baris kode harus diteliti. Kecuali kode Anda sepele, saya jamin ... perlu beberapa saat untuk mengonversi dan membuatnya berfungsi kembali setelah mengubah semuanya menjadi idiom async.
Kris
2

Anda harus menggunakan janji:

const asyncOperation = () => {
    return new Promise((resolve, reject) => {
        setTimeout(()=>{resolve("hi")}, 3000)
    })
}

const asyncFunction = async () => {
    return await asyncOperation();
}

const topDog = () => {
    asyncFunction().then((res) => {
        console.log(res);
    });
}

Saya lebih suka definisi fungsi panah. Tetapi setiap string dalam bentuk "() => {...}" juga bisa ditulis sebagai "function () {...}"

Jadi topDog tidak asinkron meskipun memanggil fungsi asinkron.

masukkan deskripsi gambar di sini

EDIT: Saya menyadari banyak kali Anda perlu membungkus fungsi async di dalam fungsi sinkronisasi ada di dalam pengontrol. Untuk situasi tersebut, inilah trik pesta:

const getDemSweetDataz = (req, res) => {
    (async () => {
        try{
            res.status(200).json(
                await asyncOperation()
            );
        }
        catch(e){
            res.status(500).json(serviceResponse); //or whatever
        }
    })() //So we defined and immediately called this async function.
}

Memanfaatkan ini dengan callback, Anda dapat melakukan bungkus yang tidak menggunakan promise:

const asyncOperation = () => {
    return new Promise((resolve, reject) => {
        setTimeout(()=>{resolve("hi")}, 3000)
    })
}

const asyncFunction = async (callback) => {
    let res = await asyncOperation();
    callback(res);
}

const topDog = () => {
    let callback = (res) => {
        console.log(res);
    };

    (async () => {
        await asyncFunction(callback)
    })()
}

Dengan menerapkan trik ini ke EventEmitter, Anda bisa mendapatkan hasil yang sama. Tentukan pendengar EventEmitter di mana saya telah mendefinisikan callback, dan memancarkan peristiwa di mana saya memanggil callback.

pengguna2485309
sumber
1

Saya tidak dapat menemukan skenario yang tidak dapat diselesaikan dengan menggunakan node-fiber. Contoh yang Anda berikan menggunakan node-fibres berperilaku seperti yang diharapkan. Kuncinya adalah menjalankan semua kode yang relevan di dalam fiber, jadi Anda tidak perlu memulai fiber baru dalam posisi acak.

Mari kita lihat contoh: Katakanlah Anda menggunakan beberapa kerangka kerja, yang merupakan titik masuk aplikasi Anda (Anda tidak dapat memodifikasi kerangka kerja ini). Kerangka kerja ini memuat modul nodejs sebagai plugin, dan memanggil beberapa metode pada plugin. Katakanlah kerangka ini hanya menerima fungsi sinkron, dan tidak menggunakan serat dengan sendirinya.

Ada pustaka yang ingin Anda gunakan di salah satu plugin Anda, tetapi pustaka ini asinkron, dan Anda juga tidak ingin mengubahnya.

Utas utama tidak dapat dihasilkan saat tidak ada serat yang berjalan, tetapi Anda masih dapat membuat plugin menggunakan serat! Cukup buat entri pembungkus yang memulai seluruh kerangka di dalam fiber, sehingga Anda dapat menghasilkan eksekusi dari plugin.

Kelemahan: Jika kerangka menggunakan setTimeoutatau Promises secara internal, maka itu akan keluar dari konteks serat. Hal ini dapat bekerja di sekitar dengan mengejek setTimeout, Promise.thendan semua event handler.

Jadi begitulah cara Anda menghasilkan serat sampai Promiseterselesaikan. Kode ini mengambil fungsi async (Janji kembali) dan melanjutkan serat saat janji diselesaikan:

framework-entry.js

console.log(require("./my-plugin").run());

async-lib.js

exports.getValueAsync = () => {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve("Async Value");
    }, 100);
  });
};

my-plugin.js

const Fiber = require("fibers");

function fiberWaitFor(promiseOrValue) {
  var fiber = Fiber.current, error, value;
  Promise.resolve(promiseOrValue).then(v => {
    error = false;
    value = v;
    fiber.run();
  }, e => {
    error = true;
    value = e;
    fiber.run();
  });
  Fiber.yield();
  if (error) {
    throw value;
  } else {
    return value;
  }
}

const asyncLib = require("./async-lib");

exports.run = () => {
  return fiberWaitFor(asyncLib.getValueAsync());
};

my-entry.js

require("fibers")(() => {
  require("./framework-entry");
}).run();

Ketika Anda menjalankan node framework-entry.jsitu akan melemparkan kesalahan: Error: yield() called with no fiber running. Jika Anda menjalankannya node my-entry.jsberfungsi seperti yang diharapkan.

Tamas Hegedus
sumber
0

Membuat sinkronisasi kode Node.js sangat penting dalam beberapa aspek seperti database. Tetapi keuntungan sebenarnya dari Node.js terletak pada kode async. Karena ini adalah utas tunggal yang tidak memblokir.

kita bisa menyinkronkannya menggunakan fungsionalitas penting Fiber () Gunakan await () dan defer () kita memanggil semua metode menggunakan await (). kemudian ganti fungsi callback dengan defer ().

Kode Async normal. Ini menggunakan fungsi CallBack.

function add (var a, var b, function(err,res){
       console.log(res);
});

 function sub (var res2, var b, function(err,res1){
           console.log(res);
    });

 function div (var res2, var b, function(err,res3){
           console.log(res3);
    });

Sinkronkan kode di atas menggunakan Fiber (), await (), dan defer ()

fiber(function(){
     var obj1 = await(function add(var a, var b,defer()));
     var obj2 = await(function sub(var obj1, var b, defer()));
     var obj3 = await(function sub(var obj2, var b, defer()));

});

Saya harap ini akan membantu. Terima kasih

Mohan Ramakrishna
sumber
0

Pola generator saat ini dapat menjadi solusi dalam berbagai situasi.

Berikut contoh perintah konsol sekuensial di nodejs menggunakan fungsi readline.question async:

var main = (function* () {

  // just import and initialize 'readline' in nodejs
  var r = require('readline')
  var rl = r.createInterface({input: process.stdin, output: process.stdout })

  // magic here, the callback is the iterator.next
  var answerA = yield rl.question('do you want this? ', r=>main.next(r))    

  // and again, in a sync fashion
  var answerB = yield rl.question('are you sure? ', r=>main.next(r))        

  // readline boilerplate
  rl.close()

  console.log(answerA, answerB)

})()  // <-- executed: iterator created from generator
main.next()     // kick off the iterator, 
                // runs until the first 'yield', including rightmost code
                // and waits until another main.next() happens
drodsou
sumber
-1

Anda tidak boleh melihat apa yang terjadi di sekitar panggilan yang menciptakan serat, tetapi lebih pada apa yang terjadi di dalam serat. Setelah Anda berada di dalam fiber, Anda dapat memprogram dengan gaya sinkronisasi. Sebagai contoh:

fungsi f1 () {
    console.log ('tunggu ...' + Tanggal baru);
    tidur (1000);
    console.log ('ok ...' + Tanggal baru);   
}

fungsi f2 () {
    f1 ();
    f1 ();
}

Serat (fungsi () {
    f2 ();
}).Lari();

Di dalam serat yang Anda panggil f1, f2dan sleepseolah-olah mereka sinkron.

Dalam aplikasi web biasa, Anda akan membuat Fiber di dispatcher permintaan HTTP Anda. Setelah Anda selesai melakukannya, Anda dapat menulis semua logika penanganan permintaan Anda dalam gaya sinkronisasi, meskipun itu memanggil fungsi async (fs, database, dll.).

Bruno Jouhier
sumber
Terima kasih Bruno. Tetapi bagaimana jika saya memerlukan gaya sinkronisasi dalam kode bootstrap yang perlu dijalankan sebelum server mengikat ke port tcp - seperti konfigurasi atau data yang harus dibaca dari db yang dibuka async? Saya mungkin berakhir dengan membungkus seluruh server.js dalam Fiber, dan saya curiga itu akan mematikan konkurensi di seluruh tingkat proses. Meskipun demikian itu adalah saran yang layak untuk diverifikasi. Bagi saya, solusi ideal harus dapat menggabungkan fungsi asinkron untuk menyediakan sintaks panggilan sinkronisasi dan hanya memblokir baris kode berikutnya dalam rantai pemanggil tanpa mengorbankan konkurensi pada tingkat proses.
abbr
Anda dapat membungkus seluruh kode bootstrap Anda di dalam satu panggilan Fiber besar. Konkurensi seharusnya tidak menjadi masalah karena kode bootstrap biasanya harus dijalankan hingga selesai sebelum Anda mulai menyajikan permintaan. Selain itu, serat tidak mencegah serat lain untuk bekerja: setiap kali Anda mencapai panggilan hasil, Anda memberi kesempatan serat lain (dan utas utama) untuk berjalan.
Bruno Jouhier
Saya telah membungkus file server.js bootstrap Express dengan fiber. Urutan eksekusi adalah apa yang saya cari, tetapi bungkus itu tidak berpengaruh pada penangan permintaan. Jadi saya rasa harus menerapkan pembungkus yang sama untuk SETIAP dispatcher. Saya menyerah pada titik ini karena tampaknya tidak ada cara yang lebih baik untuk membantu menghindari pemfaktoran ulang global. Tujuan saya adalah untuk meminimalkan dampak pada pemanggil ketika metode akuisisi data diubah dari sinkronisasi ke asinkron di lapisan DAO dan Fiber masih sedikit gagal untuk tantangan tersebut.
abbr
@fred: Tidak masuk akal untuk "menyinkronkan" aliran acara seperti penangan permintaan - Anda harus memiliki while(true) handleNextRequest()loop. Membungkus setiap penangan permintaan dalam serat akan.
Bergi
@fred: fiber tidak akan banyak membantu Anda dengan Express karena callback Express bukanlah panggilan balik lanjutan (callback yang selalu dipanggil tepat sekali, baik dengan kesalahan atau akibatnya). Tetapi serat akan menyelesaikan piramida malapetaka ketika Anda memiliki banyak kode yang ditulis di atas async API dengan callback lanjutan (seperti fs, mongodb, dan banyak lainnya).
Bruno Jouhier
-2

Saya kesulitan dengan ini pada awalnya dengan node.js dan async.js adalah perpustakaan terbaik yang saya temukan untuk membantu Anda menangani ini. Jika Anda ingin menulis kode sinkron dengan node, pendekatannya adalah dengan cara ini.

var async = require('async');

console.log('in main');

doABunchOfThings(function() {
  console.log('back in main');
});

function doABunchOfThings(fnCallback) {
  async.series([
    function(callback) {
      console.log('step 1');
      callback();
    },
    function(callback) {
      setTimeout(callback, 1000);
    },
    function(callback) {
      console.log('step 2');
      callback();
    },
    function(callback) {
      setTimeout(callback, 2000);
    },
    function(callback) {
      console.log('step 3');
      callback();
    },
  ], function(err, results) {
    console.log('done with things');
    fnCallback();
  });
}

program ini akan SELALU menghasilkan ...

in main
step 1
step 2
step 3
done with things
back in main
Michael Connor
sumber
2
asyncberfungsi dalam contoh Anda b / c itu main, yang tidak peduli dengan pemanggil. Bayangkan semua kode Anda dibungkus dalam sebuah fungsi yang seharusnya mengembalikan hasil dari salah satu panggilan fungsi asinkron Anda. Ini dapat dengan mudah dibuktikan tidak berfungsi dengan menambahkan console.log('return');di akhir kode Anda. Dalam kasus seperti itu, keluaran returnakan terjadi setelah in maintetapi sebelumnya step 1.
abbr
-11

Javascript adalah bahasa utas tunggal, Anda tidak ingin memblokir seluruh server Anda! Kode Async menghilangkan kondisi balapan dengan membuat dependensi menjadi eksplisit.

Belajar mencintai kode asinkron!

Lihat promiseskode asinkron tanpa membuat piramida neraka panggilan balik. Saya merekomendasikan pustaka promiseQ untuk node.js

httpGet(url.parse("http://example.org/")).then(function (res) {
    console.log(res.statusCode);  // maybe 302
    return httpGet(url.parse(res.headers["location"]));
}).then(function (res) {
    console.log(res.statusCode);  // maybe 200
});

http://howtonode.org/promises

EDIT: sejauh ini ini adalah jawaban saya yang paling kontroversial, node sekarang memiliki kata kunci hasil, yang memungkinkan Anda untuk memperlakukan kode asinkron seolah-olah itu sinkron. http://blog.alexmaccaw.com/how-yield-will-transform-node

roo2
sumber
1
Promise hanya mengubah parameter callback daripada mengubah fungsi menjadi sinkronisasi.
abbr
2
Anda tidak ingin sinkronisasi atau seluruh server Anda akan diblokir! stackoverflow.com/questions/17959663/…
roo2
1
Yang diinginkan adalah panggilan sinkronisasi tanpa memblokir acara lain seperti permintaan lain yang ditangani oleh Node.js. Fungsi Sync menurut definisi hanya berarti ia tidak akan kembali ke pemanggil sampai hasilnya dihasilkan (bukan hanya janji). Itu tidak mengecualikan server dari penanganan acara lain saat panggilan diblokir.
abbr
@fred: Saya pikir Anda kehilangan inti dari janji . Mereka bukan hanya abstraksi pola pengamat, tetapi mereka menyediakan cara untuk merangkai dan membuat tindakan asinkron.
Bergi
1
@Bergi, saya banyak menggunakan promise dan tahu persis fungsinya. Secara efektif semua yang dicapai adalah memecah pemanggilan fungsi asinkron tunggal menjadi beberapa pemanggilan / pernyataan. Tapi itu tidak mengubah hasilnya - ketika pemanggil kembali, itu tidak bisa mengembalikan hasil dari fungsi async. Lihat contoh yang saya posting di JSFiddle. Pemanggil dalam hal ini adalah fungsi AnticipatedSyncFunction dan fungsi async adalah setTimeout. Jika Anda bisa menjawab tantangan saya menggunakan janji, tolong tunjukkan saya.
abbr