是否可以在蓝鸟地图中绑定它?

Is it possible to bind this in bluebird map?

所以我尽我所能写了一个例子,这不是一个非常实际的例子,但我试图简化它,但我觉得我可能有试图举个例子使这个复杂化。

class add {
  constructor(baseValue) {
    this.base = baseValue;
    return new Promise((resolve, reject) => {
      resolve(this);
    });
  }
  addBase(num) {
    return new Promise((resolve, reject) => {
      resolve(this.base + num);
    });
  }
}

const values = [1,2,3,4,5];

Promise.try(() => {
  return new add(5);
}).then((add) => {
  // we want to find if a 5 exists in the results
  const addPromise = Promise.resolve(values).map(add.addBase, {concurrency: 1});
  return Promise.try(() => {
    return addPromise;
  }).then((results) => {
    for(let i = 0; i < results.length; i++) {
      if(results[i] === 10) {
        return i;
      }
    }
    // doesn't exist
    return null;
  });
}).then((result) => {
  if(result === null) {
    console.log('10 does not exist');
  } else {
    console.log('10 is at position ' + result);
  }
})
<script src="https://cdn.jsdelivr.net/bluebird/latest/bluebird.min.js"></script>

如果你运行这你会得到一个错误,你不能得到未定义的基数,这是因为蓝鸟中的映射。 const addPromise = Promise.resolve(values).map(add.addBase, {concurrency: 1}); 在进行这些调用时,是否可以通过此行将添加对象绑定到 this

你几乎已经回答了你自己的问题…

class add {
  constructor(baseValue) {
    this.base = baseValue;
    return new Promise((resolve, reject) => {
      resolve(this);
    });
  }
  addBase(num) {
    return new Promise((resolve, reject) => {
      resolve(this.base + num);
    });
  }
}

const values = [1,2,3,4,5];

Promise.try(() => {
  return new add(5);
}).then((add) => {
  // we want to find if a 5 exists in the results
  const addPromise = Promise.resolve(values).map(add.addBase.bind(add), {concurrency: 1});
  return Promise.try(() => {
    return addPromise;
  }).then((results) => {
    for(let i = 0; i < results.length; i++) {
      if(results[i] === 10) {
        return i;
      }
    }
    // doesn't exist
    return null;
  });
}).then((result) => {
  if(result === null) {
    console.log('10 does not exist');
  } else {
    console.log('10 is at position ' + result);
  }
})
<script src="https://cdn.jsdelivr.net/bluebird/latest/bluebird.min.js"></script>

这实际上比我想的要简单一些。您正在将原始函数传递给 map(),但您可能应该传递一个箭头函数。考虑这个简单的 class 和试图通过传递 add():

来使用 map() 的代码

class Test{
    constructor(n) {
        this.n = n
    }
    add(k) {
        return this.n + k
    }
}
let t = new Test(10)
let arr = [1, 2, 3]

// error TypeError: undefined is not an object (evaluating 'this.n')
arr.map(t.add)

这会引发错误,因为 map 并未从对象调用 add(),它只是认为它是一个函数。一个简单的解决方法是像这样调用地图:

class Test {
  constructor(n) {
    this.n = n
  }
  add(k) {
    return this.n + k
  }
}
let t = new Test(10)

let arr = [1, 2, 3]
let mapped = arr.map((n) => t.add(n))
console.log(mapped)

您还可以使用:

let mapped = arr.map(t.add.bind(t))

但对我来说,这更难快速阅读和理解。我不确定您的代码中所有立即解决的承诺是怎么回事,但是更改您调用 map() 的方式会使该错误消失。 (稍后出现另一个错误,您引用 i 不在范围内。)