Обіцяє, передайте додаткові параметри, щоб потім ланцюг


100

Обіцянка, лише наприклад:

var P = new Promise(function (resolve, reject) {
  var a = 5;
  if (a) {
    setTimeout(function(){
      resolve(a);
    }, 3000);
  } else {
    reject(a);
  }
});

Після того, як ми зателефонуємо, тоді метод на обіцянку:

P.then(doWork('text'));

Функція doWork виглядає приблизно так:

function doWork(data) {
  return function(text) {
    // sample function to console log
    consoleToLog(data);
    consoleToLog(b);
  }
}

Як я можу уникнути повернення внутрішньої функції в doWork, щоб отримати доступ до даних із параметрів обіцянки та тексту? Чи є хитрощі, щоб уникнути внутрішньої функції?


1
Чому хтось навмисно відмовився б від карі ? Для того, щоб використовувати ганебний bindметод? - що також надзвичайно повільно.

@ftor Я вас не розумію, чи можете ви надати якийсь код для уточнення?
Roland

Відповіді:


86

Ви можете використовувати Function.prototype.bindдля створення нової функції зі значенням, переданим її першому аргументу, як це

P.then(doWork.bind(null, 'text'))

і ви можете змінити , doWorkщоб,

function doWork(text, data) {
  consoleToLog(data);
}

Тепер textбуде фактично 'text'в doWorkі dataбуде значення, вирішене Обіцянням.

Примітка. Переконайтеся, що ви приєднали обробник відхилень до ланцюга обіцянок.


Робоча програма: Жива копія на відмову від Вабеля

function doWork(text, data) {
  console.log(text + data + text);
}

new Promise(function (resolve, reject) {
    var a = 5;
    if (a) {
      setTimeout(function () {
        resolve(a);
      }, 3000);
    } else {
      reject(a);
    }
  })
  .then(doWork.bind(null, 'text'))
  .catch(console.error);

дякую, це допомагає, я раніше спробую doWork.call (це, "текст"), але дані були замінені на "текст"
user3110667,

2
callвикликає функцію на місці, bindстворює нову функцію, однак обидва приймають контекст виконання як перший аргумент.
sdgluck

103

Мабуть, найпростіша відповідь:

P.then(function(data) { return doWork('text', data); });

Або, оскільки це позначено тегами ecmascript-6, використовуючи функції стрілок:

P.then(data => doWork('text', data));

Я вважаю це найбільш читаним, і не надто писати.


5

Використовуйте каррі.

var P = new Promise(function (resolve, reject) {
    var a = 5;
    if (a) {
        setTimeout(function(){
            resolve(a);
        }, 3000);
    } else {
        reject(a);
    }
});

var curriedDoWork = function(text) {
    return function(data) {
        console.log(data + text);
    }
};

P.then(curriedDoWork('text'))
.catch(
    //some error handling
);

b обережно з цим, якщо ви curriedDoWorkперетворюєтесь на обіцянку, виконуючи return new Promise()на першому рядку цієї функції, обіцянка виконується, як тільки ви телефонуєте curriedDoWork()(як це робиться в..then(curriedDoWork('text'))
Полум'я

@Flame: коротка відповідь, для вашої зручності ви можете перетворити обіцянку на функцію, якщо ви хочете це зробити.
герман

@yks, ви могли б вказали цей синтаксис , який є досить цікавим Const curriedWork = текст => дані => console.log (дані + текст)
Germain

1
@germain ах, так, я бачив цю форму раніше, треба любити функціональне програмування. Однак я відчуваю, що функції стрілок ламаються в якомусь браузері, тому я, як правило, зараз уникаю цього.
yks

@yks, тільки Internet Explorer не підтримує його і ніколи, через Edge, останній збір Internet Explorer був 9 грудня 2015 року. Перейдемо до ~
германія

0

Лодаш пропонує приємну альтернативу саме цій речі.

 P.then(_.bind(doWork, 'myArgString', _));

 //Say the promise was fulfilled with the string 'promiseResults'

 function doWork(text, data) {
     console.log(text + " foo " + data);
     //myArgString foo promiseResults
 }

Або якщо ви хочете, щоб у вашої функції успіху був лише один параметр (виконані результати обіцянки), ви можете використовувати його таким чином:

P.then(_.bind(doWork, {text: 'myArgString'}));

function doWork(data) {
    console.log(data + " foo " + this.text);
    //promiseResults foo myArgString
}

Це додасться text: 'myArgString'до thisконтексту в межах функції.


0

Нова відповідь на це питання полягає у використанні стрілочних функцій, які автоматично пов'язують "це" і набагато читають. Google для таких посилань, як: https://2ality.com/2016/02/arrow-functions-vs-bind.html

Ви можете встановити текст на зразок: this.text = 'text' P.then (data => doWork (data)); //this.text всередині doWork оцінить як "текст".

Це запропоновано джибом вище і що (або це!) Має бути прийнятою відповіддю зараз.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.