我應該使用return嗎?

[英]should i use `return` in Promise?


function saveToTheDb(value) {  
  return new Promise(function(resolve, reject) {
    db.values.insert(value, function(err, user) { // remember error first ;)
      if (err) {
        return reject(err); // don't forget to return here
      }
      resolve(user);
    })
  }
}

Here is the code which i see from here. i am confused about return keyword.

這是我從這里看到的代碼。我對return關鍵字感到困惑。

For resolve(user);, do i need return?

用於解析(用戶);,是否需要返回?

For reject(user);, do i need return?

對於拒絕(用戶),我需要返回嗎?

3 个解决方案

#1


30  

There is no need to use a return statement inside a new Promise() callback. The Promise constructor is not expecting any sort of return value from the callback.

不需要在新的Promise()回調中使用return語句。Promise構造函數不期望從回調返回任何類型的值。

So, the reason to use a return statement inside that callback is only to control the flow of execution in that function. If you want execution inside your callback to finish and not execute any more code within that callback, you can issue a return; at that point.

因此,在回調中使用返回語句的原因只是為了控制該函數中的執行流。如果您希望在回調中執行完成,而不是在該回調中執行任何代碼,您可以發出返回;在這一點上。

For example, you could have written your code like this with no return statement:

例如,您可以編寫這樣的代碼,但沒有返回語句:

function saveToTheDb(value) {  
  return new Promise(function(resolve, reject) {
    db.values.insert(value, function(err, user) { 
      if (err) {
        reject(err);
      } else {
        resolve(user);
      }
    });
  }
}

In this case, you used the if/else clause to make sure the flow of control in your function takes the correct path and no return was needed or used.

在本例中,使用if/else子句確保函數中的控制流采用正確的路徑,不需要或不使用返回。


A common shortcut when promisifying async functions like this is:

在促進類似這樣的異步功能時,一個常見的快捷方式是:

function saveToTheDb(value) {  
  return new Promise(function(resolve, reject) {
    db.values.insert(value, function(err, user) { 
      if (err) return reject(err);
      resolve(user);
    });
  }
}

This is not functionally different than the previous code block, but it is less typing and more compact. The return statement in front of reject(err); is only for flow of control reasons to prevent from executing the resolve(user); statement in case of error since the desired flow of control is to call reject(err) and then not execute anything else in the callback.

這與前面的代碼塊在功能上沒有什么不同,但它的輸入更少,而且更緊湊。拒絕(err)前面的返回語句;僅為流程控制原因,防止執行解決方案(用戶);由於所需的控制流是調用reject(err),然后在回調中不執行任何其他操作,因此如果出現錯誤,將使用語句。


In fact, the return statement in this last block is not actually even needed in this specific case because executing a resolve() after a reject() will not do anything since promises are latched to whichever happens first resolve or reject. But, it is generally considered poor practice to execute unnecessary code so many would argue that it is better to use flow of control structures such as if/else or return to only execute the code that is needed.

事實上,在這個特定的情況下,最后一個塊中的返回語句實際上並不需要,因為在拒絕()之后執行一個resolve()將不會做任何事情,因為承諾被鎖定在第一個解析或拒絕的情況下。但是,執行不必要的代碼通常被認為是糟糕的實踐,很多人會認為,最好使用控制結構的流,比如if/else或者返回,只執行需要的代碼。

So, this would technically work too, but is not considered a best practice because it executes unnecessary code and isn't as clearly structured:

因此,從技術上來說,這也是可行的,但並不被認為是最佳實踐,因為它執行了不必要的代碼,而且結構也不那么清晰:

function saveToTheDb(value) {  
  return new Promise(function(resolve, reject) {
    db.values.insert(value, function(err, user) {
      if (err) reject(err);
      resolve(user);
    });
  }
}

FYI, what you are doing here is called "promisifying" which makes a regular async function that works with a callback into a function that returns a promise. There are libraries and functions that will "promisify" a function or a whole object of functions (e.g. a whole API) for you in one function call so you don't have to do this manually. For example, I regularly use Bluebird which offers Promise.promisify() for promisifying a single function or Promise.promisifyAll() which will promisify all the methods on an object or prototype. This is very useful. For example, you could get promisified versions of the entire fs module with just this:

順便說一下,你在這里做的是“promisifying”,它使一個常規的異步函數與一個回調函數一起工作,變成一個返回承諾的函數。有一些庫和函數可以在一次函數調用中為您“推廣”一個函數或整個函數對象(例如,一個完整的API),因此您不必手動執行。例如,我經常使用Bluebird,它提供Promise.promisify()來促進單個函數或Promise.promisifyAll(), promisifyall()將在對象或原型上推廣所有方法。這是非常有用的。例如,您可以通過以下方法獲得整個fs模塊的升級版本:

var Promise = require('bluebird');
var fs = Promise.promisifyAll(require('fs'));

Then, you can use methods that return a promise such as:

然后,您可以使用返回承諾的方法,例如:

fs.readFileAsync("file.txt").then(function(data) {
    // do something with file.txt data here
});

#2


0  

Generally, in NodeJS, you shouldn't use the promise constructor very much.

The promise constructor is for converting APIs that don't return promises to promises. You should consider using a library that provides promisification (even if you use native promises all-around) since it provides a safe alternative that does not have subtle errors with error-handling logic.

承諾構造函數用於轉換不返回承諾的api。您應該考慮使用提供promisification的庫(即使您全面使用本機承諾),因為它提供了一個安全的替代方案,不會有錯誤處理邏輯的細微錯誤。

Automatic promisification is also considerably faster.

自動提升速度也快得多。

That said, the answer to your question is "Yes".

It is perfectly safe to do so, there is nothing special about promise constructors - they are just plain JavaScript. Domenic discusses the design of the promise constructor in his blog.

這樣做是完全安全的,承諾構造函數沒有什么特別之處——它們只是普通的JavaScript。Domenic在博客中討論了promise構造函數的設計。

It is perfectly safe (just like any other function) to return early - it is actually quite common in regular asynchronous functions.

盡早返回是完全安全的(就像任何其他函數一樣)——它實際上在常規異步函數中非常常見。

(Also, in your example code you should just use Promise.resolve, but I assume it was that simple only because it is an example).

(同樣,在示例代碼中,您應該只使用Promise。解析,但我認為之所以這么簡單,僅僅是因為它是一個示例)。

Copied this answer from duplicate

復制這個答案

#3


-1  

As @JaromandaX said in this case the return statement does not make any diference. From the docs:

正如@JaromandaX在本例中所言,返回語句沒有任何差異。從文檔:

In all cases where a promise is resolved (i.e. either fulfilled or rejected), the resolution is permanent and cannot be reset. Attempting to call resolve, reject, or notify if promise is already resolved will be a no-op.

在任何情況下,如果一個承諾得到了解決(即履行或拒絕),那么該決議是永久性的,不能被重新設定。如果承諾已經得到解決,則嘗試調用resolve、reject或通知,這將是一個禁忌。


注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2016/01/08/72ffd9189f6190b41a5297811b8fa75c.html



 
粤ICP备14056181号  © 2014-2021 ITdaan.com