如果未传递可选回调,如何使函数返回promise?

时间:2018-08-03 04:19:14

标签: javascript

我可以提出

columns: [
    cx.common.admin.tableEditColumn('id'),
    { data: 'title' },
    { data: 'remedy.0.title' },
    { data: 'additional-remedy.0.title' },
    { data: 'date_created' }

],

我找到了另一种方式

 function squareAsync(val, callback) {
if (callback) {
    setTimeout(() => {
        if (Math.random() < 0.5) {
            callback(undefined, val * val);
        }
        else {
            callback(new Error('Failed!'));
        }
    }, 2000);
}
else {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (Math.random() < 0.5) {
                resolve(val * val);
            }
            else {
                reject(new Error('Failed!'));
            }
        }, 2000);
   });
 }
}

其中哪一个更好,或者有更标准,更优雅的方法呢?我们可以使用 function squareAsync1(val, callback) { let p = new Promise((resolve, reject) => { setTimeout(() => { if (Math.random() < 0.5) { resolve(val * val); } else { reject(new Error('Failed!')); } }, 2000); }); if (callback) { p.then(d => { callback(undefined, d); }, e => { callback(e); }); } return p; } 吗?

2 个答案:

答案 0 :(得分:1)

 async function squareAsync1(val, callback) {
let p = new Promise((resolve, reject) => {
    setTimeout(() => {
        if (Math.random() < 0.5) {
            resolve(val * val);
        }
        else {
            reject(new Error('Failed!'));
        }
    }, 2000);
});
if (callback) {
    return p.then(d => {
        return callback(undefined, d);
    }, e => {
        return callback(e);
    });
 }
return p;
}

是的,您的解决方案将与异步/等待一起使用。请注意,我刚刚将return添加到了p.then

这样,您可以执行以下操作:

const x = await squareAsync1(2, (e, v) => e ? 1 : v * 2)

您将获得x的1(如果诺言被拒绝)或8(如果诺言成功)

答案 1 :(得分:1)

您可以这样做:

function squareAsync(val, callback) {
  const timeout = function(res, rej){
    setTimeout(function(){
      if (Math.random() < 0.5)
        res(val*val);
      else
        rej(new Error('Failed!'));
    }, 2000);
  }
  
  return typeof callback === 'function'
    ? timeout(callback.bind(null, undefined), callback)
    : new Promise(timeout);
}

// CALLBACK EXAMPLE
squareAsync(5, (err, val) => {
  if (err)
    console.log(`Callback: ${err}`);
  else
    console.log(`Callback: ${val}`);
})

// PROMISE EXAMPLE
squareAsync(5)
  .then(val => console.log(`Promise: ${val}`))
  .catch(err => console.log(`Promise: ${err}`))

说明

  1. 将您的setTimeout调用包装到一个包装函数timeout中,这样您就不必重复几乎相同的代码。
  2. timeout函数接受两个参数:resrej (解决并拒绝)
  3. 如果通过函数传递了回调,则返回timeout,否则返回new Promise(timeout)

现在看看发生了什么

return typeof callback === 'function'
  ? timeout(callback.bind(null, undefined), callback)
  : new Promise(timeout);

它翻译为:

if (typeof callback === 'function'){
  // Bind `null` as `this` value to `callback
  // and `undefined` as its first argument (because no error).
  // Need to to this because in `timeout` function,
  // we call `res` with only 1 argument (computed value) if success.
  const resolve = callback.bind(null, undefined);

  // Don't need to bind anything
  // because the first argument should be error.
  const reject = callback;

  // Call the function as if we are in a Promise
  return timeout(resolve, reject);
}

// Use `timeout` function as normal promise callback.
return new Promise(timeout);

希望您能理解。如果感到困惑,请随时发表评论。

More about bind.