簡體   English   中英

Node.js:異步調用后執行代碼的哪些部分?

[英]Node.js: Which parts of the code are executed following an asynchronous call?

異步調用是javascript的固有部分,使用回調通常是處理這些調用的優雅工具。

但是,我不太確定異步操作后代碼的分支是如何決定的。 例如,以下代碼會發生什么?

function f(callback) {
   value = some_async_call();
   if (value) {
       callback(value);
   }
   return(value);
}

這會發生什么? 根據我的簡短JS經驗, return會發回一個undefined值。 但是假設該value從異步調用返回true,是否會使用正確的值或undefined值調用回調?

換句話說,是否存在關於在異步調用之后立即執行哪些操作以及哪些操作被延遲直到返回值的規則?

在問之前我嘗試了什么

SFTW用於在javascript中分支異步調用,但沒有發現任何規范或決定性的內容。

你是對的,將返回undefined 在異步操作之后執行邏輯,應該將回調傳遞給該函數。 您正在嘗試以同步方式使用代碼, async/await可以幫助您解決問題。 假設some_async_call returns Promise你可以寫:

async function f(callback) {
  var value = await some_async_call();
  if (value) {
    callback(value);
  }
  return value;
}

在這種情況下,您的函數將返回值的Promise ,也將是異步的。 在這里閱讀更多。

甚至更多你不需要傳遞回調。 您可以在客戶端代碼中await您的函數並從那里執行回調。

關於分支,在不使用async/await情況下分支的唯一方法是使some_async_call接受一個接受value參數的回調:

function f(callback) {
 some_async_call(function(value) {
   if (value) {
     callback(value);
   }
 });
}

並再次重申,除了Promise之外,無法從異步方法返回值。 或者在RxJS中 Observable到。

更新:在底部添加了3種不同方法之間的實際差異

我們假設some_async_call(); 被定義為異步函數: async function some_async_call() { ... }

這個函數返回的是一個Promise ,這意味着value現在是一個promise: value.then( function(result) { } )

當我把它翻譯成代碼:

async function some_async_call() { 
    if (theMoonIsInTheRightPosition)
        return Fetch('/api/data/') // this returns a promise as well.

    return false;
}

我現在可以做兩件事:

function parentFunction(callback) {
    var promise = some_async_call();
    promise.then( callback );
    return ...; // you can't "return" the value of an async call synchronously, since it is a promise.
}

要么:

async function asyncParentFunction( callback ) {
    var value = await some_async_call();
    if (value)
        callback( value );
    return value;
}

但是,這也將父函數轉換為異步函數,這意味着該函數的立即返回值也是一個承諾。

長話短說:

您可以使用回調來流經異步函數,也可以使用promises或async / await

回調

function doStuff(callback) {
    // do asynchronous stuff
    var result = 100;
    callback(result); // once you're done with stuff
}
doStuff( function(data) { console.log('Im done!', data); } );

許諾

function doStuff() {
    return new Promise(function(resolve, reject) {
        // do asynchronous stuff
        var result = 100;
        resolve(result);
    });
}
doStuff.then(function(data) { console.log('Im done!', data); });

異步/ AWAIT

function doStuff() {
    return new Promise(function(resolve, reject) {
        // do asynchronous stuff
        var result = 100;
        resolve(result);
    });
}
(async function() { // async/await only works in async functions.
    var data = await doStuff();
    console.log('Im done!', data);
})();

正如你所看到的:promises和async / await使用相同的機制,真的值得一讀。

三者之間差異的實際例子:

回調

function fetchUserWithPosts(userId, callback) {
    fetchUser(userId, function(user) {
        fetchPostsByUserId(userId, function(posts) {
            callback({
                user: user,
                posts: posts
            });
        });
    });
}

許諾

function fetchUserWithPosts(userId) {
    return Promise.all([
        fetchUser(userId),
        fetchPostsByUserId(userId)
    ]).then(function(result) {
        return {
            user: result[0],
            posts: result[1]
        };
    });
}

異步/ AWAIT

async function fetchUserWithPosts(userId) {
    return {
        user: await fetchUser(userId),
        posts: await fetchPostsByUserId(userId);
    };
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM