В следующем примере, который я написал, показано, как
Этот рабочий пример является автономным. Он будет определять простой объект запроса, который использует объект window XMLHttpRequest
для совершения вызовов. Он будет определять простую функцию, чтобы дождаться завершения кучи обещаний.
Контекст. В этом примере запрашивается конечная точка Spotify Web API для поиска объектов playlist
для заданного набора строк запроса:
[
"search?type=playlist&q=%22doom%20metal%22",
"search?type=playlist&q=Adele"
]
Для каждого элемента новый Promise запустит блок - ExecutionBlock
, проанализирует результат, заплатит новый набор обещаний на основе массива результатов, который представляет собой список объектов Spotify user
и выполняет новый HTTP-вызов в ExecutionProfileBlock
асинхронно.
Затем вы можете увидеть вложенную структуру Promise, которая позволяет вам генерировать множественные и полностью асинхронные вложенные HTTP-вызовы и присоединять результаты к каждому подмножеству вызовов через Promise.all
.
NOTE Recent Spotify search
API-интерфейсам потребуется указать токен доступа в заголовках запроса:
-H "Authorization: Bearer {your access token}"
Итак, вы должны запустить следующий пример, вам нужно поместить маркер доступа в заголовки запроса:
var spotifyAccessToken = "YourSpotifyAccessToken";
var console = {
log: function(s) {
document.getElementById("console").innerHTML += s + "
"
}
}
// Simple XMLHttpRequest
// based on https://davidwalsh.name/xmlhttprequest
SimpleRequest = {
call: function(what, response) {
var request;
if (window.XMLHttpRequest) { // Mozilla, Safari, ...
request = new XMLHttpRequest();
} else if (window.ActiveXObject) { // Internet Explorer
try {
request = new ActiveXObject('Msxml2.XMLHTTP');
}
catch (e) {
try {
request = new ActiveXObject('Microsoft.XMLHTTP');
} catch (e) {}
}
}
// State changes
request.onreadystatechange = function() {
if (request.readyState === 4) { // Done
if (request.status === 200) { // Complete
response(request.responseText)
}
else
response();
}
}
request.open('GET', what, true);
request.setRequestHeader("Authorization", "Bearer " + spotifyAccessToken);
request.send(null);
}
}
//PromiseAll
var promiseAll = function(items, block, done, fail) {
var self = this;
var promises = [],
index = 0;
items.forEach(function(item) {
promises.push(function(item, i) {
return new Promise(function(resolve, reject) {
if (block) {
block.apply(this, [item, index, resolve, reject]);
}
});
}(item, ++index))
});
Promise.all(promises).then(function AcceptHandler(results) {
if (done) done(results);
}, function ErrorHandler(error) {
if (fail) fail(error);
});
}; //promiseAll
// LP: deferred execution block
var ExecutionBlock = function(item, index, resolve, reject) {
var url = "https://api.spotify.com/v1/"
url += item;
console.log( url )
SimpleRequest.call(url, function(result) {
if (result) {
var profileUrls = JSON.parse(result).playlists.items.map(function(item, index) {
return item.owner.href;
})
resolve(profileUrls);
}
else {
reject(new Error("call error"));
}
})
}
arr = [
"search?type=playlist&q=%22doom%20metal%22",
"search?type=playlist&q=Adele"
]
promiseAll(arr, function(item, index, resolve, reject) {
console.log("Making request [" + index + "]")
ExecutionBlock(item, index, resolve, reject);
}, function(results) { // Aggregated results
console.log("All profiles received " + results.length);
//console.log(JSON.stringify(results[0], null, 2));
///// promiseall again
var ExecutionProfileBlock = function(item, index, resolve, reject) {
SimpleRequest.call(item, function(result) {
if (result) {
var obj = JSON.parse(result);
resolve({
name: obj.display_name,
followers: obj.followers.total,
url: obj.href
});
} //result
})
} //ExecutionProfileBlock
promiseAll(results[0], function(item, index, resolve, reject) {
//console.log("Making request [" + index + "] " + item)
ExecutionProfileBlock(item, index, resolve, reject);
}, function(results) { // aggregated results
console.log("All response received " + results.length);
console.log(JSON.stringify(results, null, 2));
}
, function(error) { // Error
console.log(error);
})
/////
},
function(error) { // Error
console.log(error);
});
Я подробно рассмотрел это решение здесь .
ОК, поэтому я решил проблему. Файл формата должен быть добавлен с использованием -f и пути к файлу. Его можно создать путем запуска bcp без какого-либо формата и заказать его для сохранения файла формата на диск. Затем мы можем использовать этот файл формата, поэтому ему больше не нужно отвечать на эти вопросы, а сам файл не имеет дополнительных данных и может быть открыт без проблем
Слава богу, благодаря @ user_0 answer и загадочному ответу и комментарию @ user3494351 и комментарию, и этот древний пост форума Я, наконец, понял это через несколько часов, ударяя головой о стену.
Проблема в том, что BCP любит добавлять дополнительные 8 байтов в файл по умолчанию. Это искажает файл и делает невозможным его открытие, если вы просто используете флаг native -n.
Однако BCP позволяет вам указать файл формата в качестве вывода, который может позволить вам сказать, чтобы он не добавлял дополнительные 8 байт. Таким образом, у меня есть таблица, которую я создал (которая будет использоваться в курсоре) на SQL Server, которая имеет только ОДИН ROW и ONE COLUMN с моими двоичными данными. Таблица должна существовать при запуске первой команды.
В командной строке сначала вам нужно сделать это:
bcp MyDatabase.MySchema.MyTempTable format nul -T -n -f formatfile.fmt
Это создает formatfile.fmt в каталоге, в котором вы находитесь. I сделал на диске E: \. Вот как это выглядит:
10.0
1
1 SQLBINARY 8 0 "" 1 MyColumn ""
Это 8, там есть переменная, которая указывает, сколько байтов добавить в ваш файл. Это ублюдок, который развращает ваши файлы. Измените этот присосок на 0:
10.0
1
1 SQLBINARY 0 0 "" 1 MyColumn ""
Теперь просто запустите свой BCP-скрипт, снимите флаг -n и включите флаг -f:
bcp "SELECT MyColumn FROM MyDatabase.MySchema.MyTempTable" queryout "E:\MyOutputpath" -T -f E:\formatfile.fmt
BCP добавляет информацию в свой файл. Всего несколько данных, но вы не экспортируете только файл jpg.
Вы говорите 167 KB, но смотрите реальные байты, а не округленное измерение. Будет разница.
Вы не можете экспортировать изображение через BCP.