简体   繁体   English

有没有办法知道 function 是否在 promise 中被调用?

[英]Is there a way to know if a function is called inside a promise?

Let's say I have this code, and I have written a function called handleSmell() in a package that others can use:假设我有这段代码,并且我在 package 中编写了一个名为handleSmell()的 function,其他人可以使用:

const streamSomeUrl = (url='https://salmon.net/river') => {

  console.info('...connecting...');
  const { data, headers } = await axios({
    url,
    method: 'GET',
    responseType: 'stream',
  });
  return new Promise((resolve, reject) => {
    data.on('data', (chunk) => {
       if(smellsFunny(chunk)) {
         // promise aware function
         handleSmell(chunk) // <--- behaves differently inside a promise. 
         // E.g. prints  "Smell inside a promise" 
       }
    });
  })
}

Is there a way, that the function handleSmell to tell if it's in a promise or not?有没有办法让handleSmell处理气味来判断它是否在 promise 中? By that I mean, it would behave differently to here:我的意思是,它的行为与这里不同:

readFile('/etc/fish', (err, data) => {
  if(smellsFunny(data)) {
     // promise aware function
     handleSmell(data) // <--- behaves differently inside a promise.
     // E.g. prints  "Smell *not* inside a promise" 
     ...
     }
});

I'm trying to figure out if I can do with without taking reject/resolve callbacks in to the handleSmell function (and then if missing, know I'm not in a promise).我试图弄清楚是否可以在不接受拒绝/解决回调到handleSmell function 的情况下进行处理(然后如果丢失,知道我没有承诺)。

As far as I'm aware I can't use the fact that different data is passed through, both chunk and data are strings/buffers?据我所知,我不能使用传递不同数据的事实, chunkdata都是字符串/缓冲区?

Is this at all possible?这是可能吗? I'm motivated by this question , mainly this bit from an answer:我受到这个问题的启发,主要来自答案:

Any time you are inside of a promise callback, you can use throw.任何时候你在 promise 回调中,你都可以使用 throw。 However, if you're in any other asynchronous callback, you must use reject.但是,如果您在任何其他异步回调中,则必须使用拒绝。

new Promise(function() {
  setTimeout(function() {
    throw 'or nah';
    // return Promise.reject('or nah'); also won't work
  }, 1000);
}).catch(function(e) {
  console.log(e); // doesn't happen
});

My preference is to throw, but I want to know if I call a reject callback (ie from the parent reject) it will work:我的偏好是抛出,但我想知道如果我调用拒绝回调(即来自父拒绝)它会起作用:


function handleSmell(suspectData, reject=False) {
  const inPromise = //?????
  if (inPromise && reject) {
    return reject('SMELLY REJECT!')
  } else if (inPromise) {
    throw new Error('SMELLY THROWN!')
  } else { console.error('SMELLY NON-PROMISE!') }
}
// Both these should work
new Promise(function() {
  setTimeout(function() {
    handleSmell('cheese');
}).catch(function(e) {
  console.log(e); // doesn't try to throw
});

new Promise(function(resolve, reject) {
  setTimeout(function() {
    handleSmell('cheese', reject);
  }, 1000);
}).catch(function(e) {
  console.log(e); // this works
});

The alternative is promisifying the non-promise (as per link).另一种方法是承诺不承诺(根据链接)。

But can I avoid that if possible?但如果可能的话,我可以避免吗?

Is this at all possible?这是可能吗?

No, you cannot do that, and no, you shouldn't do that.不,你不能那样做,不,你不应该那样做。 What a function does should depend on its arguments, not on where it was called from. function 所做的应该取决于它的 arguments,而不是从哪里调用它。

I'm motivated by this question, mainly this bit from an answer:我受到这个问题的启发,主要来自答案:

Any time you are inside of a promise callback, you can use throw.任何时候你在 promise 回调中,你都可以使用 throw。 However, if you're in any other asynchronous callback, you must use reject.但是,如果您在任何其他异步回调中,则必须使用拒绝。

Well, handleSmell is not defined in a callback, it's a standalone synchronous function, so it should simply throw an exception.好吧, handleSmell没有在回调中定义,它是一个独立的同步 function,所以它应该简单地抛出一个异常。

The proper way to call such a function is either from within a try block, or from within a promise ( then ) callback.调用此类 function 的正确方法是从try块中或从 promise ( then ) 回调中。

new Promise((resolve, reject) => {
  setTimeout(() => {
    try {
      resolve(handleSmell('cheese'));
    } catch(err) {
      reject(err);
    }
  });
}).then(console.log, console.error);
new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('cheese');
  }, 1000);
}).then(handleSmell).then(console.log, console.error);
//      ^^^^^^^^^^^
// or .then(res => handleSmell(res)) for verbosity

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM