Javascript 当使用 Promises 时,每个 then() 都应该返回一个值或抛出

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/48750847/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 04:14:01  来源:igfitidea点击:

Each then() should return a value or throw when using Promises

javascriptnode.js

提问by Tometoyou

I have a few async methods that I need to wait for completion before I return from the request. I'm using Promises, but I keep getting the error:

我有一些异步方法需要在从请求返回之前等待完成。我正在使用 Promises,但我不断收到错误消息:

Each then() should return a value or throw // promise/always-return

Why is this happpening? This is my code:

为什么会这样?这是我的代码:

router.get('/account', function(req, res) {
  var id = req.user.uid
  var myProfile = {}
  var profilePromise = new Promise(function(resolve, reject) {
    var userRef = firebase.db.collection('users').doc(id)
    userRef.get()
      .then(doc => { // Error occurs on this line
        if (doc.exists) {
          var profile = doc.data()
          profile.id = doc.id
          myProfile = profile
          resolve()
        } else {
          reject(Error("Profile doesn't exist"))
        }
      })
      .catch(error => {
        reject(error)
      })
  })
  // More promises further on, which I wait for
})

采纳答案by Bergi

Just avoid the Promiseconstructor antipattern! If you don't call resolvebut return a value, you will have something to return. The thenmethod should be used for chaining, not just subscribing:

只要避免Promise构造函数反模式!如果您不调用resolve而是返回一个值,那么您将有一些东西要return. 该then方法应该用于链接,而不仅仅是订阅

outer.get('/account', function(req, res) {
  var id = req.user.uid
  var userRef = firebase.db.collection('users').doc(id)
  var profilePromise = userRef.get().then(doc => {
    if (doc.exists) {
      var profile = doc.data()
      profile.id = doc.id
      return profile // I assume you don't want to return undefined
//    ^^^^^^
    } else {
      throw new Error("Profile doesn't exist")
//    ^^^^^
    }
  })
  // More promises further on, which I wait for:
  // profilePromise.then(myProfile => { … });
})

回答by Marlhex

回答by Santosh Shinde

In your case firebase.db.collection('users').doc(id)returning promiseitself, please check firebase snippet to herefor node-js.

在您firebase.db.collection('users').doc(id)返回promise自身的情况下,请在此处查看 node-js 的firebase 代码段。

If you have multiple promises and you need to call them one by one then use Promises chaining.

如果您有多个 Promise 并且需要一个一个地调用它们,则使用Promises chaining

Please check this articlethis will help you.

请查看这篇文章,这将对您有所帮助。

Use following code in your case,

在您的情况下使用以下代码,

          router.get('/account', function(req, res) {

            var id = req.user.uid;
            var myProfile = {};

            var userRef = firebase.db.collection('users').doc(id)

            userRef.get()
            .then(doc =>  {

                if (!doc || !doc.exists) {
                   throw new Error("Profile doesn't exist")
                }

                var profile = doc.data();
                profile.id = doc.id;
                myProfile = profile;

               return myProfile;

            })
            .catch(error => {
              console.log('error', error);
            })

          })

And use Promise.all if you have multiple promises and you want's to execute them in once.

如果您有多个 Promise 并且希望一次执行它们,请使用 Promise.all。

The Promise.all(iterable)method returns a single Promise that resolves when all of the promises in the iterable argument have resolved or when the iterable argument contains no promises. It rejects with the reason of the first promise that rejects.

Promise.all(iterable)方法返回一个 Promise,当 iterable 参数中的所有承诺都已解决或当 iterable 参数不包含承诺时,该 Promise 会解决。它以第一个拒绝的承诺的原因拒绝。

For example:

例如:

  var promise1 =  new Promise((resolve, reject) => {
    setTimeout(resolve, 100, 'foo1');
  });
  var promise2 =  new Promise((resolve, reject) => {
    setTimeout(resolve, 100, 'foo2');
  });
  var promise3 =  new Promise((resolve, reject) => {
    setTimeout(resolve, 100, 'foo3');
  });

  Promise.all([promise1, promise2, promise3])
  .then(result =>  console.log(result))
  //result [foo1, foo2, foo3] 

Hopes this will help you !!

希望这会帮助你!!

回答by Abhin Krishna KA

If you can't fix this issue but still want to run your code...

如果您无法解决此问题但仍想运行您的代码...

open   : eslintrc.json file (search from project root directory)
search : 'promise/always-return'
change : Case 1: if (existing value is 2) => change to 1
         Case 2: else if(existing value is "error" => change to "warn")

It will make this error into warning, but be careful with it... Also use eslint plungin in your editor to remind of good practice. Otherwise you won't get any promise/always-return related warnings.

它会将这个错误变成警告,但要小心... 也在你的编辑器中使用 eslint plungin 来提醒良好的实践。否则,您将不会收到任何与承诺/始终返回相关的警告。

Also make sure you find the right eslintrc.json if more than 1 appears on your search

如果您的搜索中出现 1 个以上,请确保您找到了正确的 eslintrc.json