Проблема с передачей контекста в цепочке Bluebird Promise - PullRequest
1 голос
/ 04 марта 2020

Я столкнулся с ситуацией, когда мне нужно передать некоторые значения в обработчик Promise. Ниже приведен пример ситуации

function promiseFunct(x){
    return new Promise(function(resolve, reject){
       if(x>0) resolve(x);
       else if(x==0) resolve(1);
       else resolve(0);
  });
}

promiseFunct(-100).then(function(response){
  var someObj = { len: 124 };
  return promiseFunct(response).bind(someObj);
}).then(function(response){
    if(this.len) console.log(this.len); //not getting access here, this is Window
});

Я пытаюсь связать someObj, а затем получить доступ к нему в обработчике, но безуспешно. Есть ли какое-то элегантное решение для передачи какого-либо объекта в обработчик обещаний, кроме передачи в Promise и последующего разрешения внутри Promise?

Ответы [ 2 ]

1 голос
/ 04 марта 2020

Нашли простое решение, но нет гарантии, что оно самое элегантное.

promiseFunct(-100).bind({}).then(function(response){
  this.len = 124 ;
  return promiseFunct(response);
}).then(function(response){
    if(this.len) console.log(this.len); // showing 124
});

С bind({}) установкой собственного контекста цепочки Promise, который, например, не пересекается с Window. Если бы у меня было значение len снаружи, я мог бы использовать bind({len: len}) Тогда я мог бы использовать this.propertyName, чтобы получить или установить желаемое свойство для использования в следующих обработчиках.

0 голосов
/ 04 марта 2020

Сначала посмотрим, что происходит не так:

promiseFunct(-100).then(function(response){
  var someObj = { len: 124 };
  return promiseFunct(response).bind(someObj);
})

возвращает связанное обещание от обработчика выполнения then.

Код обещания ждет, пока связанное обещание не будет выполнено, прежде чем передать его состояние (выполнено или отклонено) и значение (данные или причина отклонения) в цепочке обещаний. Чтобы сделать это, он внутренне вызывает then для связанного обещания, чтобы получить его результат, и используются внутренние обработчики, которые вызываются со связанным значением this - что они просто игнорируют.

Хотя В документации Bluebird говорится

... Кроме того, обещания, полученные из связанного обещания, также будут связаны обещаниями с тем же thisArg ...

, что не относится к этому случаю: все обещания в цепочке обещаний создаются синхронно при определении цепочки, до того, как начинается какая-либо асинхронная обработка цепочки.

Поскольку цепочки обещаний передают только одно значение между обработчиками простейшим подходом может быть передача объекта пространства имен с любым количеством других значений по мере необходимости. Поскольку последующим обработчикам уже нужно было знать, где искать дополнительные данные, изменение не должно быть слишком большим:

function promiseFunct(x){
    return new Promise(function(resolve, reject){
       if(x>0) resolve(x);
       else if(x==0) resolve(1);
       else resolve(0);
  });
}
promiseFunct(-100).then(function(response){
console.log( "response " + response);
  var someObj = { len: 124 };
  var ns = {response, rest: someObj};
  return ns;
}).then(function({response, rest}){
    if(rest.len) console.log(rest.len);
    console.log(response);
}); 
...