用 Promises 返回的数据替换出现的文本
Replace text occurrences with data returned by Promises
我有一个博客-post是这样的:
var post ="## Cool Post [embed]https://soundcloud.com/wonnemusik/teaser-schotone-dear-thomson-button-remix[/embed]"
+ "Here comes another one [embed]https://soundcloud.com/straightech-bonn-podcast/straightech-and-friends-7-oscar-ozz[/embed]";
现在,对于 [embed]soundcloud-url[/embed]
的每次出现,我都需要调用他们的 API 端点 http://api.soundcloud.com/resolve.json?url=soundcloud-url&client_id=my-id
,解析返回的 JSON 并将 [embed]
替换为我的自己的标记。
我如何通过 Promises 使用它?
var post ="## Cool Post [embed]https://soundcloud.com/wonnemusik/teaser-schotone-dear-thomson-button-remix[/embed]"
+ "Here comes another one [embed]https://soundcloud.com/straightech-bonn-podcast/straightech-and-friends-7-oscar-ozz[/embed]"
var re = /\[embed\](.*)\[\/embed\]/gm;
var m;
do {
m = re.exec(post);
if (m) {
var apiCallUrl = "http://api.soundcloud.com/resolve.json?url=" + m[1] '&client_id=...'
request(apiCallUrl).then(function(body) {
var trackinfo = JSON.parse(body[0].body)
return trackinfo.title
}
}
} while (m);
// have all promises fulfilled and old embed in post-var replaced
我没有具体使用 bluebird
,但通常有 an all
method that wraps an array of promises (or takes promises as arguments). A glance at the API documentation for bluebird shows they do have an all
方法供您使用。您需要在 do/while 循环中创建一个 promises 数组,然后在末尾调用 all
:
var resultPromises = [];
var m;
do {
m = re.exec(post);
if (m) {
var apiCallUrl = "http://api.soundcloud.com/resolve.json?url=" + m[1] '&client_id=...'
resultPromises.push(request(apiCallUrl));
}
} while (m);
// have all promises fulfilled and old embed in post-var replaced
Promise.all(resultPromises).then(function (results) {
// do stuff.
});
现在,如果您想用承诺的结果替换原始文本,您还需要将匹配项存储在一个数组中。 then
的 results
参数将是一个响应数组,按照它们最初添加到数组中的顺序排列。所以,你可以这样做:
var resultPromises = [];
var matches = [];
var m;
do {
m = re.exec(post);
if (m) {
var apiCallUrl = "http://api.soundcloud.com/resolve.json?url=" + m[1] '&client_id=...'
resultPromises.push(request(apiCallUrl));
matches.push(m);
}
} while (m);
var i = 0;
// have all promises fulfilled and old embed in post-var replaced
Promise.all(resultPromises).then(function (results) {
// haven't tested this. Will leave as practice for the OP :)
post = post.replace(matches[i], results[i].body[0].body.title);
i += 1;
});
您可以使用处理异步回调的this replace
function:
var post = "## Cool Post [embed]https://soundcloud.com/wonnemusik/teaser-schotone-dear-thomson-button-remix[/embed]"
+ "Here comes another one [embed]https://soundcloud.com/straightech-bonn-podcast/straightech-and-friends-7-oscar-ozz[/embed]"
var re = /\[embed\](.*)\[\/embed\]/gm;
return replaceAsync(post, re, function(m, url) {
var apiCallUrl = "http://api.soundcloud.com/resolve.json?url=" + url + '&client_id=…'
return request(apiCallUrl).then(function(res) {
return JSON.parse(res[0].body).title;
});
});
我有一个博客-post是这样的:
var post ="## Cool Post [embed]https://soundcloud.com/wonnemusik/teaser-schotone-dear-thomson-button-remix[/embed]"
+ "Here comes another one [embed]https://soundcloud.com/straightech-bonn-podcast/straightech-and-friends-7-oscar-ozz[/embed]";
现在,对于 [embed]soundcloud-url[/embed]
的每次出现,我都需要调用他们的 API 端点 http://api.soundcloud.com/resolve.json?url=soundcloud-url&client_id=my-id
,解析返回的 JSON 并将 [embed]
替换为我的自己的标记。
我如何通过 Promises 使用它?
var post ="## Cool Post [embed]https://soundcloud.com/wonnemusik/teaser-schotone-dear-thomson-button-remix[/embed]"
+ "Here comes another one [embed]https://soundcloud.com/straightech-bonn-podcast/straightech-and-friends-7-oscar-ozz[/embed]"
var re = /\[embed\](.*)\[\/embed\]/gm;
var m;
do {
m = re.exec(post);
if (m) {
var apiCallUrl = "http://api.soundcloud.com/resolve.json?url=" + m[1] '&client_id=...'
request(apiCallUrl).then(function(body) {
var trackinfo = JSON.parse(body[0].body)
return trackinfo.title
}
}
} while (m);
// have all promises fulfilled and old embed in post-var replaced
我没有具体使用 bluebird
,但通常有 an all
method that wraps an array of promises (or takes promises as arguments). A glance at the API documentation for bluebird shows they do have an all
方法供您使用。您需要在 do/while 循环中创建一个 promises 数组,然后在末尾调用 all
:
var resultPromises = [];
var m;
do {
m = re.exec(post);
if (m) {
var apiCallUrl = "http://api.soundcloud.com/resolve.json?url=" + m[1] '&client_id=...'
resultPromises.push(request(apiCallUrl));
}
} while (m);
// have all promises fulfilled and old embed in post-var replaced
Promise.all(resultPromises).then(function (results) {
// do stuff.
});
现在,如果您想用承诺的结果替换原始文本,您还需要将匹配项存储在一个数组中。 then
的 results
参数将是一个响应数组,按照它们最初添加到数组中的顺序排列。所以,你可以这样做:
var resultPromises = [];
var matches = [];
var m;
do {
m = re.exec(post);
if (m) {
var apiCallUrl = "http://api.soundcloud.com/resolve.json?url=" + m[1] '&client_id=...'
resultPromises.push(request(apiCallUrl));
matches.push(m);
}
} while (m);
var i = 0;
// have all promises fulfilled and old embed in post-var replaced
Promise.all(resultPromises).then(function (results) {
// haven't tested this. Will leave as practice for the OP :)
post = post.replace(matches[i], results[i].body[0].body.title);
i += 1;
});
您可以使用处理异步回调的this replace
function:
var post = "## Cool Post [embed]https://soundcloud.com/wonnemusik/teaser-schotone-dear-thomson-button-remix[/embed]"
+ "Here comes another one [embed]https://soundcloud.com/straightech-bonn-podcast/straightech-and-friends-7-oscar-ozz[/embed]"
var re = /\[embed\](.*)\[\/embed\]/gm;
return replaceAsync(post, re, function(m, url) {
var apiCallUrl = "http://api.soundcloud.com/resolve.json?url=" + url + '&client_id=…'
return request(apiCallUrl).then(function(res) {
return JSON.parse(res[0].body).title;
});
});