2015-12-30 4 views
1

Я изо всех сил стараюсь реализовать обещания. (I думаю Я их понимаю, но часто получаю неожиданные результаты, поэтому, возможно, я этого не делаю.)Подробная информация о Promises; примеры

Рассмотрите этот код, пожалуйста.

function ap() { 
    return new Promise(function(resolve, reject) { 
    console.log('function ap starting want this'); 
    function ender() { 
     console.log('function ender starting want this'); 
     return resolve('ender'); 
     console.log('after return in ender don\'t want this'); //#1 
    } 
    ender() 
    console.log('after function ender and its resolve ' + 
     'for Promise don\'t want this'); //#2 
    }) // Promise 
} // ap 

console.log('---') 
ap() 
.then(function(result, error) { 
    if (error) console.log ('error ' + error.message) 
    console.log('function ap result result=' + result + 
    ' want this') 
}) 

Я включил в консоль.log много мест и указал, хочу ли я их распечатать, учитывая мое понимание обещаний.

я ожидал:

function ap starting want this 
function ender starting want this 
function ap result result=ender want this 

Я не хочу, чтобы последний вызов console.log внутри Эндера (// # 1), потому что это после возвращения достаточно, чтобы вытащить меня из Эндер сферы. Мой линтер утверждал, что он «недоступен»; звучит согласованно.

Мне не нужен консольный вызов после вызова ender (// # 2), потому что ender, в конце концов, разрешил Promise, который является практически всей областью действия; было бы неудивительно выйти из обещания и выйти ap.

я получил:

function ap starting want this 
function ender starting want this 
after function ender and its resolve for Promise don't want this 
function ap result result=ender want this 

Вопрос: Является ли это правильный урок? Язык не распознает известность Promise in ap scope. «Возврат» был достаточным для того, чтобы оставить область эндера, но не область действия. «Решение (« ender ») было достаточным для решения обещания. Цепочная цепочка продолжалась после вызова ender, поэтому напечатан нежелательный оператор. Программисты должны и отправлять функции обратного вызова в Promise и выйти из сферы действия прилагаемой функции.

Исходя из предположения, что это правда, я написал этот код.

function bp() { 
    return new Promise(function(resolve, reject) { 
    console.log('function bp starting want this') 
    function ender() { 
     console.log('function ender starting want this'); 
     return resolve('ender'); 
     console.log('after return in ender don\'t want this'); 
    } 
    ender(); return; 
    console.log('after function ender and its resolve ' + 
     'for Promise don\'t want this'); 
    }) // Promise 
} // bp 

Это отличается от первого кода только тем, что я добавил возврат сразу после вызова ender. Единственный путь через ender включает «return resolve (« ender »)»; если я добавлю «return» сразу после вызова ender, он вытащит меня из области bp, и все может быть хорошо.

Принимая за другое имя функции, я ожидал того же результата, что и раньше, и получил этот результат. Похоже, мой «извлеченный урок» может быть близок к правильному ответу.

Далее я написал этот код (пожалуйста, игнорируйте ссылки на j, они отвлекают меня, я думал, что мне нужны они для последующего вопроса, но это не сработало в первый раз, сделав этот пост короче!):

function cp(i, j) { 
    return new Promise(function(resolve, reject) { 
    console.log('function cp starting   i=' + i + 
     ' j=' + j + ' want this'); 
    function ender() { 
     console.log('function cp ender starting i=' + i + 
     ' j=' + j + ' want this'); 
     i++; 
     let reps = 3; 
     if (i < reps) { 
     cp(i, j) 
     .then(function(result, error) { 
      if (error) { 
      console.log('*** error i=' + i + 
       ' j=' + j + ' msg=' + error.message + 
       ' want this'); 
      return reject(error); 
      } 
      console.log('in cp cp('+ i + ', ' + j + 
      ')  result=' + result + ' want this'); 
      return resolve(result); 
     }) // cp(i) callback 
     console.log('in cp i=' + i + ' j=' + j + '' + 
      ' in ender after reject, resolve, and ' + 
      'callback don\'t want this'); //#3 
     } // if (i < reps) 
     console.log('in cp resolving i=' + i + 
      ' j=' + j + '  want this') 
     return resolve('done'); 
    } // ender 
    ender(); return; 
    console.log('in cp i=' + i + ' j=' + j + 
     ' after ender call and return for cp scope' + 
     ' don\'t want this'); 
    }) // Promise 
} // cp 

Он добавляет рекурсию и сразу же следует за вызовом эндера с «возвратом»; он удаляет недостижимый код, идентифицированный linter; все может пойти хорошо.

Я получил

function cp starting   i=0 j=0 want this 
function cp ender starting i=0 j=0 want this 
function cp starting   i=1 j=0 want this 
function cp ender starting i=1 j=0 want this 
function cp starting   i=2 j=0 want this 
function cp ender starting i=2 j=0 want this 
in cp resolving i=3 j=0  want this 
in cp i=2 j=0 in ender after return, resolve, and callback don't want this 
in cp resolving i=2 j=0  want this 
in cp i=1 j=0 in ender after return, resolve, and callback don't want this 
in cp resolving i=1 j=0  want this 
in cp cp(2, 0)  result=done want this 
in cp cp(1, 0)  result=done want this 
function cp result result=done want this 

Вот что я ожидал получить, за исключением того, что // # 3 печатает, потому что язык не признает, что все возможности были покрыты либо «отказаться» или «разрешить» в блок обратного вызова; он продолжал выполнять команды, неразумно помещенные в эту позицию.

Эти биты кода являются моделями программы, с которыми я по-прежнему сталкиваюсь.Вскоре я надеюсь смоделировать другое поведение, которое меня удивляет.

На более общем уровне: что делают первые таймеры с обещаниями, часто не понимают обещаний? Как мы можем получить более высокую уверенность в правильном управлении потоком выполнения? Какие ресурсы особенно полезны для объяснения на этом уровне детализации? Я буду признателен за любые советы на этом более общем уровне.

Заранее спасибо ...

+1

OMG, serioursly ??? попытайтесь опубликовать соответствующую информацию, а не целую историю. – dreamweiver

+0

Почему вы даже используете 'j'? – thefourtheye

+2

Вопросы, подобные *** Что делают первые таймеры с обещаниями часто не понимают про обещания? *** слишком широки для переполнения стека. Можно написать книгу или очень длинную статью по этой теме. Этот сайт работает лучше всего с кратким вопросом, который имеет ясный ответ в нескольких параграфах, которые не основаны прежде всего на мнениях. Кроме того, запрос на сторонние ресурсы считается ** вне темы ** для переполнения стека. Этот вопрос необходимо тщательно очистить или закрыть. – jfriend00

ответ

2

Истинный ответ здесь является то, что отвергают и решимость являются просто обратные вызовы и отметьте отбракованных/решительность обещание. Они не изменяют исходный JavaScript-способ работы, что является вашим предположением. «Мне не нужен консольный вызов после вызова ender, потому что ender (// # 2), в конце концов, разрешил Promise, что практически все пп сфера, это не было бы ничего удивительного, чтобы выйти из посыла и выхода ар "

Вызов reject или resolve просто означает, что вы будете работать с этим обещанием.. Это не означает, что функция, в которой вы это сделаете, сразу выйдет. Итак, обязательно если хотите - используйте return.

И это то же со следующим примером:

if (i < reps) { 
    cp(i, j) 
    .then(...) 

    console.log(... // you DON'T want this 
} 

Ну да, конечно, вы получите его, несмотря вы не хотите его. Вы создали заявление if, в котором вы делаете магию Promise, а затем используете console.log. Поэтому JavaScript не волнует, является ли это обещанием или нет - он просто выполняет вещи один за другим.

Если вы прочитали немного больше о обещаниях, вы поймете, что они представляют собой чистый JavaScript с try-catch внутри них, поэтому, если ошибка возникает, они могут поймать ее и вызвать обратный вызов отказа (обычно с .catch(function(err){})).

Снова - Promises не изменяйте способ работы JavaScript! И все, что вы сказали, очень логично и должно произойти именно так. И это потому, что вы ожидаете, что обещания заблокируют ваш другой код, чего не произойдет вообще :)

+0

Спасибо тонны за толерантность и ответ. У меня серьезные проблемы с пониманием неожиданного поведения обещаний. Они отсутствуют во всех моих книгах. Мои поиски в Интернете не находят эту деталь. У меня нет эксперта по JavaScript в кругу знакомых. Я согласен с другими, что SO работает лучше всего при ответе на конкретные вопросы синтаксиса; Я не хочу злоупотреблять им. Мне нужен еще один указатель, например, когда я задавал асинхронные вопросы, и кто-то сказал что-то вроде: «Посмотрите на Bluebird!» Этот человек прав: обещания тонны лучше, хотя я бы хотел, чтобы у меня было больше документации. – BaldEagle

+1

Я думаю, что [Q-документация] (https://github.com/kriskowal/q) может помочь. Это просто очередная реализация обещаний. Удачи! –

+0

Еще раз спасибо. Я прочитаю документацию Q. В то же время, следующий вопрос, пожалуйста. Мы согласны: «// НЕ НЕ ЕСТЬ» (из фрагмента кода). Что вызывает эти результаты? Казалось бы, это не более достижимо, чем «// # 3», что следует за возвратом. Оператор, вызывающий выходные данные, синтаксически находится на том же уровне, что и 'cp (i, j)', и весь этот трафик покинул область «ender». Смущенный. Благодарю. – BaldEagle