Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: Интересная штука с Promise.all

Добрый день.
К примеру, в цикле я создаю массив промисов, которые выполняют get запрос, и на каждой итерации немного меняется url запроса.
var arr = [];
        for (let i=1; i<=10; i++){
            arr[i] = new Promise((resolve,reject)=>{
                var xhr = new XMLHttpRequest();
                xhr.open('GET', 'https://jsonplaceholder.typicode.com/users/'+i, true);
                xhr.onload = function() {
                    if (this.status === 200) {
                        resolve(this.response);
                    } else {
                        var error = new Error(this.statusText);
                        error.code = this.status;
                        reject(error);
                    }
                };
                xhr.onerror = function() {
                    reject(new Error("Network Error"));
                };
                xhr.send();
            });
        }
        Promise.all(arr).then(
            (resolve) => {
                console.log("Ответ сервера: " + resolve)
            },
            (reject) => {
                console.log("Ошибка: " + reject)
            }
        );

Этот код работает, можете прям в консоли браузера запустить.

Но если вместо стандартного XHR использовать $.ajax, почему то работать всё перестаёт (если быть точным, вместо объектов в консоль выводится их стандартный метод toString - [object Object]):
var arr = [];
        for (let i=1; i<=10; i++){
            arr[i] = new Promise((resolve,reject)=>{
               $.ajax({
                    url: 'https://jsonplaceholder.typicode.com/users/'+i,
                    success: function (data) {
                        resolve(data);
                    },
                    error: function (jqXHR, textStatus) {
                        reject(textStatus);
                    }
                })
            });
        }
        Promise.all(arr).then(
            (resolve) => {
                console.log("Ответ сервера: " + resolve)
            },
            (reject) => {
                console.log("Ошибка: " + reject)
            }
        );

То же можно запустить в консоле.

Кто скажет - в чём дело?
Ответ:
// console.log("Ответ сервера: " + resolve)
console.log("Ответ сервера: ")
console.log(resolve)
// или
console.log("Ответ сервера: ", resolve)
// и можно посмотреть typeof что-то там
console.log(typeof resolve)
Вопрос: Как передать два значения внутрь promise js

Доброго времени суток! Работаю с приватным апи инстаграма, пытаюсь передать внутрь промиса (тот что после комментария в коде) 2 значения: мне бы хотелось передать айди пользователя и переменную lenta, на данном этапе удается передать только lenta:

'use strict';
var InstagramPrivateAPI = {};

InstagramPrivateAPI = {};
InstagramPrivateAPI.V1 = require(__dirname + '/client/v1');
InstagramPrivateAPI.Helpers = require(__dirname + '/helpers');
var acc = require(__dirname + "/client/v1/account");
var med = require(__dirname + "/client/v1/media")

var Promise = require('../bluebird');
var _ = require('../lodash/');

module.exports = InstagramPrivateAPI;

var Client = require('instagram-private-api').V1;
var device = new Client.Device('maksgmn');
var storage = new Client.CookieFileStorage(__dirname + '/cookies/maksgmn.json');
var session = new Client.Session(device, storage);

acc.searchForUser(session, 'kaigreene')
    .then(function(profile) {
        return profile.id
    })
    .then(function(someId) {
        var feed = new Client.Feed.UserMedia(session, someId);
        var lenta = Promise.mapSeries(_.range(0, 1), function() {
            return feed.get();
        })
        return lenta
    })
    //that one promise that needs lenta and user id to be transfered
    .then(function(results) {
        // result should be Media[][]
        var media = _.flatten(results);
        var urls = _.map(media, function(medium) {
            return medium.params.imageVersions2.candidates[0].url
        });
        console.log(urls)
    })


В результате console.log(urls) получается следующее:

[ 'https://scontent-arn2-1.cdninstagram.com/vp/6af16d285248021beb138878d39300f5/5C7ABDF2/t51.2885-15/e35/44564146_322592125137172_4748922672367052265_n.jpg?ig_cache_key=MTkxNTA2MzY3NjkyMDg3NzI4NQ%3D%3D.2',
  'https://scontent-arn2-1.cdninstagram.com/vp/fafb1cbedf2f2ee526b53bbbe19242e0/5BF37B8A/t51.2885-15/e15/p640x640/43536314_2236965789913961_7161939884150660296_n.jpg',
  'https://scontent-arn2-1.cdninstagram.com/vp/40aa382750e5e94a6e66d57c61381280/5C7E3B85/t51.2885-15/e35/44183920_263573101019253_2196926879861470922_n.jpg?ig_cache_key=MTkxNDI0NTA3MjY5NjQ0Mzg2MQ%3D%3D.2',
  'https://scontent-arn2-1.cdninstagram.com/vp/0f494a3130df8f5e9020adba2aaeaaa1/5C8D533C/t51.2885-15/e35/44453843_206191696937914_2654101859534502211_n.jpg?ig_cache_key=MTkxNDA4NDAwNzQ1NTExMjY3Mw%3D%3D.2',
  'https://scontent-arn2-1.cdninstagram.com/vp/891e76d89e68cef102ca82891bd79500/5C7D169D/t51.2885-15/e35/45513332_314414985821365_5157081956783129672_n.jpg?ig_cache_key=MTkxNDAxOTA3MjAzNzQ2OTc0OA%3D%3D.2',
  'https://scontent-arn2-1.cdninstagram.com/vp/8630ce604e8fc13c4b0f8dea529066c3/5BF360C2/t51.2885-15/e15/44277878_2176945342563453_2262613550408503718_n.jpg',
  'https://scontent-arn2-1.cdninstagram.com/vp/10c7c4f145e8c749d9865b9042b594ba/5C6D275A/t51.2885-15/e35/44589483_282353665729077_4185404619021489633_n.jpg?ig_cache_key=MTkxMzQ2NTEyMjA3MDQ3Mjk2NA%3D%3D.2',
  'https://scontent-arn2-1.cdninstagram.com/vp/c99a00b3d36a5013736920475b98cadb/5C8D2738/t51.2885-15/e35/44850363_1912754462367214_2546260771931931006_n.jpg?ig_cache_key=MTkxMzMwMzc3ODc4ODY5NDI0Mg%3D%3D.2',
  'https://scontent-arn2-1.cdninstagram.com/vp/b850a45fe4cc20a93da64857aee9575c/5C8D1984/t51.2885-15/e35/44634212_1869528946493492_7969207514966425740_n.jpg?ig_cache_key=MTkxMjc0MTYxMDc4NzgwOTAzNQ%3D%3D.2',
  'https://scontent-arn2-1.cdninstagram.com/vp/28e6be91c8fc996dfc47b8ea3e9781d6/5BF3CAE9/t51.2885-15/e15/43398735_115170416088701_3256913169852741968_n.jpg',
  'https://scontent-arn2-1.cdninstagram.com/vp/60e627e88aeef3ded3466d1e8a80f6fd/5BF3E157/t51.2885-15/e15/43258810_358264328256668_5269209695486174863_n.jpg',
  'https://scontent-arn2-1.cdninstagram.com/vp/85487f3fb5b805ce3fc63b40a9d5e121/5BF35B86/t51.2885-15/e15/s640x640/43504006_685794225133434_1066643086450380052_n.jpg' ]


Следующий код (возвращается id и lenta) по какой-то причине не хочет работать:

'use strict';
var InstagramPrivateAPI = {};

InstagramPrivateAPI = {};
InstagramPrivateAPI.V1 = require(__dirname + '/client/v1');
InstagramPrivateAPI.Helpers = require(__dirname + '/helpers');
var acc = require(__dirname + "/client/v1/account");
var med = require(__dirname + "/client/v1/media")

var Promise = require('../bluebird');
var _ = require('../lodash/');

module.exports = InstagramPrivateAPI;

var Client = require('instagram-private-api').V1;
var device = new Client.Device('maksgmn');
var storage = new Client.CookieFileStorage(__dirname + '/cookies/maksgmn.json');
var session = new Client.Session(device, storage);

acc.searchForUser(session, 'kaigreene')
    .then(function(profile) {
        return profile.id
    })
    .then(function(someId) {
        var feed = new Client.Feed.UserMedia(session, someId);
        var lenta = Promise.mapSeries(_.range(0, 1), function() {
            return feed.get();
        })
        return {id : someId, fd : lenta}
    })
    //that one promise that needs lenta and user id to be transfered
    .then(function(results) {
        // result should be Media[][]
        var media = _.flatten(results.fd);
        var urls = _.map(media, function(medium) {
            return medium.params.imageVersions2.candidates[0].url
        });
        console.log(urls)
    })



Подскажите как быть тут?
Ответ: Большое спасибо, очень помогли, видимо еще буду создавать темы на форуме, в целом у меня уже получился парсер, код ниже, только я не знаю как его нормально заставить работать в многопоток, взаимодействовать с клиентом и щас разберусь с прокси

'use strict';
var InstagramPrivateAPI = {};

InstagramPrivateAPI = {};
InstagramPrivateAPI.V1 = require(__dirname + '/client/v1');
InstagramPrivateAPI.Helpers = require(__dirname + '/helpers');
var acc = require(__dirname + "/client/v1/account");
var med = require(__dirname + "/client/v1/media")

var Promise = require('../bluebird');
var _ = require('../lodash/');

module.exports = InstagramPrivateAPI;

var Client = require('instagram-private-api').V1;
var device = new Client.Device('maksgmn');
var storage = new Client.CookieFileStorage(__dirname + '/cookies/maksgmn.json');
var session = new Client.Session(device, storage);


acc.searchForUser(session, 'kaigreene') //поиск id пользователя
    .then(function(profile) {
        return profile.id
    })
    .then(function(someId) {  //получение промиса lenta
        var feed = new Client.Feed.UserMedia(session, someId);
        var lenta = Promise.mapSeries(_.range(0, 1), function() {
            return feed.get();
        }).then(function(lenta) {
        	return {id: someId, fd : lenta}
        })
        return lenta
    })
    .then(function(results) {  //обработка промиса и получение ленты пользователя
        // result should be Media[][]
        var media = _.flatten(results.fd);
        var urls = _.map(media, function(medium) {
            return medium.params.imageVersions2.candidates[0].url
        })
        return {id : results.id, links : urls}
    })
    .then(function(mediaAndId) {
    	acc = acc.getById(session, mediaAndId.id)
    		.then(function(account) {
    			//console.log(account.params)
    			let avatar = account.params.profilePicUrl;
    			let fullName = account.params.fullName;
    			let bio = account.params.biography;
    			let media0 = mediaAndId.links[0];
    			let media1 = mediaAndId.links[1];
    			let media2 = mediaAndId.links[2];
    			let media3 = mediaAndId.links[3];
    			let media4 = mediaAndId.links[4];

    			console.log(avatar);
    			console.log(fullName);
    			console.log(bio);
    			console.log(media0);
    			console.log(media1);
    			console.log(media2);
    			console.log(media3);
    			console.log(media4);
    		})
    })
Вопрос: jquery 2 promise

loadDetail() {

		var defer = $.Deferred()

		this.setState({bla-bla}, (event) => {
			this.ajaxGetDetail(this.state.openedBidId).then( (json) => {
				this.setState({
					bla-bla
				}, () => {

					if (this.transmissionCollection.length === 0) {
						this.ajaxRequestTransmission().then( (result) => {
							result.map( (item)=>{
								let obj = {}
								obj[`${item.id}`] = item.name
								this.transmissionCollection.push( obj )
							})

							let transmission_value = blabla

							this.setState({ blabla1 }, () => {
								return defer.promise();
							})

						})

					} else {

						let transmission_value = blabla
							
						this.setState({ blabla2 }, () => {
							return defer.promise();
						})

					}
				})

			});
		});
	}


this.loadDetail().then (() => {
	console.log('bla')
})



не пойму почему ругается на самый последний then: Cannot read property 'then' of undefined
Ответ:
Сообщение от alexandr2006
Вот же возвращаю:

return defer.promise();

Другое дело что может в jquery 2 как-то подругому надо
«return defer.promise();» возвращается в callback'e метода «setState» (и не факт, что этот метод вообще что-то возвращает).
Даже если «setState» возвращает что-либо, то это «что-либо» так и останется в callback'e асинхронного запроса.
Ну и асинхронные запросы устроены так, что код продолжит выполняться не дожидаясь окончания запроса.
Это я к тому, что getDetail наверняка нифига не возвращает.
Вопрос: Чейнинг promise через array.reduce

Привет.
Не могу понять поведения при чейнинге через reduce. Картина такая
function f(number, x) {
    return new Promise(resolve => {
        setTimeout(() => {
            console.log(number);
            resolve(number);
        }, x)
    });
}

const answer = [f(1, 1000), f(2, 3000), f(3, 2000)]
    .reduce((previousValue, currentValue) => previousValue.then(currentValue));

answer.then(() => console.log('last'));


По моей логике, reduce должен был вернуть promise который я мог бы дальше чейнить, но на итоге, 1 чейн прицепленный к результату reduce вызываеться одновременно с 1 promise. Почему такое поведение?
Ответ:
Сообщение от рони
Spirtikys,
а вместо картинки, разместить код никак?
Заменил.
Но с проблемой разобрался, возможно перегрелся. Я передавал в чейнинг promise, в то время как then принимает function, итог -> это все проваливалось и попросту отрабатывало по таймингу
Вопрос: Как асинхронно вызвать resolve() вне Promise?

Всем привет! Понадобился Promise, который бы выполнялся, когда объект с данными создан. Необходимо, чтобы сторонний код "приостанавливал" выполнение моего скрипта, пока объект не будет готов.

Я считаю, что нет необходимости запихивать длинные куски кода в Promise только ради того, чтобы вызвать resolve() или reject().
Поэксперементировал с аксессорами...

var setter;
var promise = new Promise(function(resolve, reject) {
	setter = function(value) {
		if(value) {
			resolve();
		}
	};
});

Object.defineProperty(this, "objectCreated", {
	set: setter,
	get: function() {
		return promise;
	}
});

// много строк спустя...

this.objectCreated = true;


Hо пришлось отказаться от этой идеи, поскольку появляются лишние переменные. И выглядит это ужасно. Думаю, более элегантным (по аналогии с Promise.resolve()) решением проблемы является метод Promise.prototype.resolve(), который заставляет выполниться Promise.

Promise.prototype.resolve = function(value) {
	// как здесь вызвать resolve() ?
};
Ответ: Malleys,
Rx.js это модульная библиотека, как и Lodash. Не нужно подключать её целиком, если скажем в скриптах используется Observable как сущность и 3-4 оператора. Достаточно подключить только нужное. А задачи, решаемые через промисы, можно решать и потоками, только делать это более качественно.

Вот так например выглядит автокомплит с википедии.
import { Subject }  from 'rxjs/Subject';

private searchTermStream = new Subject<string>();

searchTermStream
      .debounceTime(300)
      .distinctUntilChanged()
      .switchMap((term: string) => this.wikipediaService.search(term));

search(term: string) { this.searchTermStream.next(term); }
Вопрос: Непонятный Unhandled promise rejection

Немогу понять, почему поведение разное.

В таком варианте все работает, как ожидалось:
const debug = require("debug")("m");

const promise = new Promise((resolve, reject) => {
	setTimeout(() => {
		reject("promise rejected");
	}, 1000);
});

promise.then(
	v => {
		debug("resolve", v);
	},
	e => {
		debug("reject", e);
	},
);

Ставлю catch вместо обработчика reject
const debug = require("debug")("m");

const promise = new Promise((resolve, reject) => {
	setTimeout(() => {
		reject("promise rejected");
	}, 1000);
});

promise.then(v => {
	debug("resolve", v);
});

promise.catch(e => {
	debug("catch: ", e);
	return;
})


работает так же, но nodejs кричит UnhandledPromiseRejectionWarning. Как понимать этот варнинг?
Ответ: Круто.

Т.е. если промис может реджектиться, то надо, либо then делать с двумя параметрами, либо далеть цепочку then...catch, чтобы отловить отклоненные промисы, возвращенные этими 'неявными' функциями (кстати, отсутствие onFulfilled функции в then в такой же ситуации никаких варнингов не вызывает).

А где в стандарте описана эта ситуация с неявной подстановкой второго параметра, никак не могу найти.
Вопрос: Promise

Добрый день!
Осваиваю промисы.
'use strict';

// сделать запрос
httpGet('/article/promise/user.json')
  // 1. Получить данные о пользователе в JSON и передать дальше
  .then(response => {
    console.log(response);
    let user = JSON.parse(response);
    return user;
  })
  // 2. Получить информацию с github
  .then(user => {
    console.log(user);
    return httpGet(`https://api.github.com/users/${user.name}`);
  })
  // 3. Вывести аватар на 3 секунды (можно с анимацией)
  .then(githubUser => {
    console.log(githubUser);
    githubUser = JSON.parse(githubUser);

    let img = new Image();
    img.src = githubUser.avatar_url;
    img.className = "promise-avatar-example";
    document.body.appendChild(img);

    setTimeout(() => img.remove(), 3000); // (*)
  });

Как в цепочке из 1 'user' передать в 3.
Ответ: Агнец за бортом,

Да, вроде оно! Спасибо!
Вопрос: Порядок выполнения then в promise

Добрый день! Проблема с пониманием promise

function func() {
        return new Promise(resolve => resolve())
    }

    func()
        .then(() => {
             setTimeout(() => console.log(1), 0)
             return func()
        })
        .then(() => console.log(2))


Если последующий then должен ждать выполнение предыдущего, почему выводит 2 потом 1? Буду благодарен за помощь
Ответ: Какой же бред я написал. Всем спасибо за объяснения! Теперь все понятно.
Вопрос: Promise подгрузка контента с .json

Добрый день.
Хочу написать функцию, которая будет подгружать контент с какого-нибудь .json документа (например: ) с помощью promise на чистом JS.
Ответ: Спасибо.
Вопрос: Events как альтернатива Promise

Добрый день!

Для текстового редактора делаю рекурсивный обход DOM (записываю в массив parrents и sibling).



Ниже тестовый пример.

В функции nextsibling рекурсивно делаю проход по nextsibling элементам и когда их уже нет,то возвращаю количество символов.


Для получения асинхронного значения из функции nextsibling я создал новое событие, которое уже потом вызывается.

Работать с событиями в данной ситуации мне удобнее, чем через Promise.

Вопрос. Правильно ли ли так делать - использовать события для получения асинхронного значения, которые вызываются только принудительно

function testy(){
        var finallength; 



        function nextsibling(node){
           if(node){
                if (node.nodeType==1){
                    elems.rightsibling.push({node:node.nodeName,length:node.TextContent.length})
                    rightlength+=node.textContent.length;     
                }
                 else{
                     rightlength+=node.textContent.length;//длина siblings
                 }
                nextsibling(node.nextSibling)
            }else{  //когда элементов нет
                finallength=rightlength; //global var - длина символов
             var eventforsibling = new CustomEvent('eventforsibling');//новое событие
                document.body.dispatchEvent(eventforsibling) //вызов
            } 
        }
        
    function parentnodes(node,stopnode){
      // Listen for the event.
            document.body.addEventListener('eventforsibling', function () {      alert( finallength) });

        }
        parentnodes(node,stopnode);

}
Ответ: Да и вообще, у тебя фигня какая то. Код твой синхронен. Ты бы мог вместо этого
var eventforsibling = new CustomEvent('eventforsibling');//новое событие
 document.body.dispatchEvent(eventforsibling) //вызов

просто вызывать alert( finallength), и было бы то же самое. Ты написал синхронный код через асинхронную жопу. Смысл то какой в этом?